如何使用Webrtc、Websocket和Django构建随机视频聊天Web应用程序。
大学二年级时,我和朋友经常在 Omegle 上花上几个小时,与来自世界各地的陌生人聊天。聊天总是充满乐趣和惊喜——你永远不知道接下来会遇到谁。Omegle 关闭后,留下了一片空白。我们怀念那些随机联系带来的兴奋,于是我就想,“为什么不自己做一个呢?”
在这篇博客中,我将详细介绍使用 WebRTC 和 WebSockets 设计和构建此类平台的过程,重点介绍我面临的挑战以及如何克服这些挑战。读完这篇博客后,您不仅会了解它的工作原理,而且还会有一个坚实的基础来开始构建自己的实时通信应用程序
我目前正在开展一个名为 Noto Chats 的项目,该项目包括此随机视频聊天功能以及其他一些令人兴奋的功能。该系统经过全面测试,运行顺畅。
这是 ramdomvideo 聊天应用程序的代码链接 https://github.com/Arsh910/RandomVideo-Chat-app
技术栈
前端:ReactJS 用于构建交互式用户界面。
后端:用于处理 WebSocket 连接的 Django 通道。
信令协议:WebSockets 建立 WebRTC 连接。
媒体流:WebRTC 用于点对点视频和音频通信。
设计

双方都会尝试建立连接,先建立连接的一方将继续进行
设计组成部分:
如果你不熟悉 WebRTC 的工作原理,请观看我学习的这个视频。以下是组件的简要概述
**1. 客户端 1 和客户端 2**
这些代表尝试连接的两个用户。每个客户端负责创建要约、将其发送到服务器并响应收到的要约。
类比:将客户端 1 和客户端 2 想象成两个想要交谈的人。他们彼此尚不认识,但渴望交谈。每个人都主动伸出手去,等待对方回应。
**2. 服务器**
服务器充当媒人的角色。它不处理实际对话,但通过在客户端之间传递提议和答案并帮助交换连接详细信息来促进介绍。
类比:想象一下,一个共同的朋友在聚会上介绍两个人。朋友没有加入他们的谈话,但确保他们知道对方的姓名和电话号码,然后开始交谈。
**3. 对等连接**
PeerConnection 是建立两个客户端之间直接连接的机制。它管理媒体(音频/视频)的交换,并确保连接一旦建立就保持稳定。如上图中的 peer1 和 peer 2。
类比:PeerConnection 就像两栋房子之间的一条安全、私密的隧道。一旦隧道建成,里面的人就可以传递纸条、交谈,甚至寄送包裹,而不会被别人看到。
**4. ICE 候选人**
ICE(交互式连接建立)候选是直接连接的构建块。这些是 PeerConnection 尝试用来建立最佳连接的路由和网络路径。
类比:ICE 候选者就像地图,显示连接两栋房屋的多条道路。连接会找到最佳道路(最短、最平坦)并使用它确保快速可靠的路线。
**5. 提议与答复**
连接过程始于一个客户端(呼叫者)创建一个请求并通过服务器将其发送给另一个客户端。第二个客户端(接收者)创建一个答案并将其发回。此交换设置了连接。
类比:想象一个人发了一封信说:“我们做个朋友吧!”另一个人回复说:“当然,我也想这样!”一旦他们同意,友谊就开始了。
**6. 曲目(音频/视频流)**
轨道是指建立连接后在客户端之间共享的媒体流(音频和视频)。
类比:音轨就像是来自两个摄像头和麦克风的实时直播。每个人都可以实时看到和听到对方分享的内容,就像实时视频通话一样。
**7. 信号传输过程**
信号传输过程包括通过服务器交换要约、答案和 ICE 候选。这可确保两个客户端都拥有建立直接 PeerConnection 所需的信息。
类比:信号传递过程就像一个邮政系统,在两个想要联系的人之间传递信息。邮递员(服务员)确保信件(提议、答案)到达正确的收件人,这样对话才能开始。
双重角色的挑战
要理解设计,首先要掌握一个关键的挑战。
在传统的电话通话中,连接过程涉及一个人充当呼叫者,另一个人充当接收者。然而,在像这样的聊天应用中,情况有所不同。在这里,每个用户都在发起连接并等待其他人接受连接。这意味着每个人都必须同时充当呼叫者和接收者,从而创建一个两个角色合并以实现无缝连接的系统。
这就是我使用两个对等连接(peer1 和 peer2)的原因。
一些重要功能:
**OnIceCandidate函数**
处理 ICE 候选交换以建立对等连接。当从 STUN 服务器收到 Ice 候选时,它会将 ICE 候选发送到服务器。
**OnTrackFunc**
处理从对等端接收到的媒体轨道(音频/视频)。当对等端传输轨道时激活。在接收方界面上显示媒体。
**处理冰**
处理从其他客户端收到的冰候选。它添加收到的冰候选并将它们添加到对等连接。
**获取随机用户**
此函数从在线用户列表中随机选择一个用户(不包括当前用户)。如果列表为空,则会抛出错误。这确保了聊天的公平随机配对。
**发送匹配**
此函数向服务器发送针对选定随机用户的连接请求。它构造一个 WebSocket 消息,通知服务器连接意图。
**检查匹配**
此函数验证服务器的响应是否确认匹配成功。它检查其他人是否选择了此用户。它检查此用户是否选择了其他用户。它检查 calling_clicked 标志是否为真(其他用户也点击了呼叫,这一点很重要)。
如果所有条件都满足,则返回 true;否则,返回 false。此步骤可确保在继续操作之前正确验证连接。
**示例来了解匹配过程**

双方都会发送和接收,先接收的一方获胜
Webrtc连接流程
**对等点 1 和对等点 2**
为了建立连接,两个对等点(对等点 1 和对等点 2)扮演着不同的角色:
同行 1:负责创建提议并接收答复。
对等方 2:处理该提议,生成答案并将其发回。
连接过程
匹配成功后,连接过程如下:
**1 初始化对等体 1:**
在两个客户端(例如,客户端 1 和客户端 2)上都创建了对等体 1。
与 Peer 1 相关的有两个关键事件:
OnTrackFunc:管理来自另一端的传入音频/视频流。
OnIceCandidateFunc:每当从 STUN 服务器接收到新的候选时,就将 ICE 候选发送到服务器。
**2 创建并发送要约:**
对等体 1 生成一个要约,并将其设置为其本地描述 (localDescription)。
两个客户端都会将该优惠发送给匹配的用户(通过信令服务器)。
**3 与同行 2 一起处理报价:**
收到报价后,双方都会创建 Peer 2。
与 Peer 1 类似,Peer 2 使用 OnTrackFunc 和 OnIceCandidateFunc 事件进行初始化。
收到的报价被设置为Peer 2的remoteDescription。
**4 生成并发送答案:**
对等点 2 生成一个答案,并将其设置为其 localDescription。
双方将此答案发送回另一个客户端(通过服务器)。
**5 完成连接:**
一旦收到答复,就将其设置为 Peer 1 的 remoteDescription。
两个客户端现在都拥有建立直接连接所需的信息。

双方都将发送和接收
**6 处理 ICE 候选人:**
当 ICE 候选被交换时,OnIceCandidateFunc 被触发。
接收到的 ICE 候选对象使用 handle_ice 函数进行处理,该函数根据连接设置将它们添加到适当的对等体(对等体 1 或对等体 2)。
**7 设置媒体流:**
当接收到媒体轨道(音频/视频)时,会触发 OnTrackFunc 事件。
这可确保远程视频和音频流显示在两个客户端上。

双方都将发送和接收
由于用户选择的随机性和处理延迟,连接过程不会在两端同时发生。首先完成设置的客户端将成为“呼叫者”,而另一个客户端则充当“接收者”。
一旦 WebRTC 连接成功建立,两个用户都可以享受无缝的视频聊天体验。
结束通话
正确结束 WebRTC 通话对于避免将来连接时出现问题(例如资源泄漏或重新连接时出错)至关重要。以下是正确处理通话终止的详细指南:
**1 删除 ICE 候选人:**
ICE 候选用于建立对等体之间的连接。
在结束通话之前,清除所有存储的 ICE 候选项,以确保它们不会干扰未来的连接。
**2 通知其他客户:**
通知另一个客户通话即将结束。
这可以通过信令服务器来完成,以正常终止双方的连接。
**3 从对等连接中删除轨道:**
删除与对等连接相关的任何媒体轨道(音频/视频)以释放资源。
这可以防止通话结束后媒体流继续。
**4 重置呼叫状态:**
将变量 calling_clicked 设置为 null(或应用程序中的等效值)。
这可确保应用程序知道没有正在进行的活动通话。
将 Peer 1 和 Peer 2 重置为空。
这将释放为对等连接分配的内存并避免意外重用旧对象。
将 remoteStream 设置为 null。
这可以确保远程音频/视频流从应用程序界面中清除。

只有一方,因为只有一个客户端启动结束
总结
构建随机视频聊天应用程序与使用它一样令人兴奋!这个过程伴随着相当多的挑战和学习机会,但看到你的创作栩栩如生的满足感确实令人欣慰。
作为一名三年级计算机科学专业的学生,我将自己的热情和好奇心倾注到了这个项目中。虽然我已尽最大努力确保一切顺利进行,但总有改进的空间。如果您发现任何缺陷或有改进该项目的建议,请随时与我联系 - 我很乐意从您的见解中学习!
因此,拿起您的键盘,深入研究代码,谁知道呢 - 您可能正在创造在线交流领域的下一个大事件。
祝你编码愉快!🎉