[{"data":1,"prerenderedAt":459},["ShallowReactive",2],{"post-zh-sg-2020-06-15-how-to-make-a-video-chat-app":3},{"post":4,"newer":425,"older":425,"hasTranslation":44},{"id":5,"title":6,"body":7,"cardImg":425,"date":426,"description":427,"excerpt":428,"extension":429,"figCaption":425,"img":430,"lang":431,"listed":44,"meta":432,"navigation":44,"path":436,"readingTime":437,"seo":438,"slug":439,"stem":440,"tagList":441,"__hash__":458},"posts\u002Fposts\u002Fzh-sg\u002F2020-06-15-how-to-make-a-video-chat-app.md","如何创建一个视频聊天应用?",{"type":8,"value":9,"toc":403},"minimark",[10,14,17,20,23,30,33,45,50,53,64,70,73,78,81,86,93,99,104,107,110,113,118,121,138,143,146,164,172,174,177,181,184,187,191,194,197,201,204,208,211,214,217,220,229,236,239,242,245,252,254,258,261,264,267,275,278,281,284,287,290,293,296,307,311,314,317,324,328,331,338,341,347,349,352],[11,12,13],"p",{},"常见的视频应用利用了一种叫做 WebRTC 的技术。WebRTC 让开发者能够基于 web 交换数据和媒体文件的应用，可以用于大家日常使用的浏览器。这是近十年来发生的技术转变，过去只能通过 flash 之类的插件实现这一功能。",[11,15,16],{},"即使你没听说过 WebRTC，你多半已经用过它了。Whatapps、Facebook、Google handout 等都用了 WebRTC。WebRTC 是 Web Real-Time Communications 的简称，可以直接连接浏览器。这项技术已经存在了至少 7 年，但我终于赶上了! 我成功创建了自己的 WebRTC 应用，通过亲手实践来更好地理解 WebRTC 这一工具。",[11,18,19],{},"这是我的新玩具，亲手创建的 WebRTC 应用程序：web.phuaxueyong.com",[11,21,22],{},"本文会讨论一些比较宽泛的话题：",[24,25,26],"ol",{},[27,28,29],"li",{},"WebRTC 如何工作？",[11,31,32],{},"魔法其实并不神奇，只是背后隐藏的大量工作。就像鸭子一样，看上去只是在水面上优雅地游弋。但水面之下却是频繁地划动。",[34,35,38],"div",{"className":36},[37],"video-embed",[39,40],"iframe",{"src":41,"frameBorder":42,"allow":43,"allowFullScreen":44},"https:\u002F\u002Fwww.youtube.com\u002Fembed\u002F9siLfUXJLuw","0","accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",true,[46,47,49],"h3",{"id":48},"_2-运行-webrtc-应用需要哪些组件","2. 运行 WebRTC 应用需要哪些组件？",[11,51,52],{},"Web 应用程序有不同的组件。大多数看不见、摸不着，比如服务器。但它们就像汽车发动机，开车的时候看不到（除非你开的是一辆道奇 Charger R\u002FT），但这并不意味着发动机不存在。",[11,54,55,60],{},[56,57],"img",{"alt":58,"src":59},"","https:\u002F\u002Fmk0cfstest0sltokv8ce.kinstacdn.com\u002Fwp-content\u002Fuploads\u002F2019\u002F07\u002F1970_Charger_O.jpg",[61,62,63],"em",{},"Source: carsforsale",[11,65,66],{},[67,68,69],"strong",{},"3. STUN 服务器的作用是什么？",[11,71,72],{},"这一节会简单讲下 STUN 服务器的工作细节（整个通讯过程中哪个阶段需要 STUN 服务器，STUN 服务器如何工作）。",[11,74,75],{},[67,76,77],{},"4. TURN 服务器的作用是什么？",[11,79,80],{},"这一节会讲什么时候需要 TURN  服务器。不是所有情况下都需要使用 TURN 服务器，不过在一些无法直接连接的场合需要使用这个组件。",[11,82,83],{},[67,84,85],{},"5. 不同使用场景下 WebRTC 的架构选择及优化空间",[11,87,88,89,92],{},"WebRTC 主要有 4 种架构。你用 zoom 的时候有没有好奇过一台服务器如何处理 160 个成员参加的会议？这里没有魔法，实际上这需要传输",[67,90,91],{},"大量","数据，10 分钟的视频传输的数据可能需要以 TB 为单位计量。",[94,95,96],"blockquote",{},[11,97,98],{},"选取适合业务用例的架构意味着已经成功了一半。",[11,100,101],{},[67,102,103],{},"6. 如何测试 WebRTC 以及可供尝试的一些免费资源",[11,105,106],{},"摆弄我的新玩具的时候，我找到了值得一试的一些工具和资源，可以用在简单 WebRTC 应用的不同组件上。",[11,108,109],{},"让我们开动吧！",[111,112],"hr",{},[114,115,117],"h2",{"id":116},"_1-webrtc-如何工作","1. WebRTC 如何工作？",[11,119,120],{},"开始视频聊天会话时，首先需要向房间发信号，表示已经到了。告知其他人已经到了称为信令（Signalling）。如果你是第一个到的人，从技术上讲，你仍然会打招呼，不过没人回应而已。",[11,122,123,124,131,132,137],{},"用术语说，信令是交互式连接创建框架（",[125,126,130],"a",{"href":127,"rel":128},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FInteractive_Connectivity_Establishment",[129],"nofollow","Interactive Connectivity Establishment"," Framework）的一部分，是通过交换媒体信息来相互查找、协调通讯的过程。信令基于会话描述协议（",[125,133,136],{"href":134,"rel":135},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSession_Description_Protocol",[129],"SDP","）收集网络信息，包括用于交换媒体的 IP 地址和端口。",[94,139,140],{},[11,141,142],{},"会话描述协议（Session Description Protocol，SDP）是用来宣布、管理会话邀请的标准方法。它以文本格式表示浏览器的功能和偏好设置。",[11,144,145],{},"浏览器连接其他客户端时，通过 SDP 交换的信息包括：",[147,148,149,152,155,158,161],"ul",{},[27,150,151],{},"开启、关闭通讯的会话控制信息。",[27,153,154],{},"错误信息。",[27,156,157],{},"媒体元数据，比如编解码器及其设置、带宽和媒体类型。",[27,159,160],{},"密钥数据，用于建立安全连接。",[27,162,163],{},"网络数据，比如公网 IP 和端口。",[11,165,166,169],{},[56,167],{"alt":58,"src":168},"https:\u002F\u002Fwww.html5rocks.com\u002Fen\u002Ftutorials\u002Fwebrtc\u002Finfrastructure\u002Fjsep.png",[61,170,171],{},"The architecture of how your WebRTC application will look like",[111,173],{},[114,175,49],{"id":176},"_2-运行-webrtc-应用需要哪些组件-1",[46,178,180],{"id":179},"_1-你需要一个用户界面","1. 你需要一个用户界面",[11,182,183],{},"需要有个 web 应用，在页面加载或点击按钮时建立连接，接着显示聊天室成员发送的视频数据。",[11,185,186],{},"用术语说，需要创建 RTCPeerConnection，并发送给远程的聊天室成员，保存在他们的机器上。web 应用开发完毕后，需要托管在 web 服务器上，以供其他聊天室成员访问。",[46,188,190],{"id":189},"_2-你需要一个信令服务器","2. 你需要一个信令服务器",[11,192,193],{},"还记得我们之前提到的信令吗？它用来向某一特定聊天室的所有成员表示你已经就位。当你进入聊天室时，已经加入聊天室的每个成员都会通过 SDP 协议记录你的远程信息和细节，并将这些信息保存到他们的机器上——准备接收你的媒体数据。",[11,195,196],{},"技术上说，WebRTC 负责 SDP 信息的创建和处理，但不负责发送和接收 SDP 信息。因此，需要一个服务器来传输 SDP 信息。通常会用 websocket 服务器完成连接初始化和传输。",[46,198,200],{"id":199},"_3-你需要一个-stun-服务器","3. 你需要一个 STUN 服务器",[11,202,203],{},"这个服务器用于获取远程成员的公网 IP。为了避免过多涉及一些技术细节，我们假设每个成员都有一个公网 IP 供 STUN 服务器获取。这些信息会作为 SDP 信息的一部分在你加入聊天室时发送给聊天室成员。",[46,205,207],{"id":206},"_4-你可能需要一个-turn-服务器","4. 你可能需要一个 TURN 服务器",[11,209,210],{},"成员之间可能无法直接建立连接，因此需要 TURN 服务器作为一个中间人转发消息。参见 [Quora 上的这个问答][quora]。",[114,212,69],{"id":213},"_3-stun-服务器的作用是什么",[11,215,216],{},"STUN 是 NAT 会话穿透应用程序（Session Traversal Utilities for NAT）的简称。通讯双方都需要知道对方的 IP 地址和 UDP 端口。",[11,218,219],{},"不管用什么架构，我们总是需要一个信令服务器用于注册成员和表示在场，也需要一个 TURN 服务器穿透网络，并确保内网 IP 可以映射到公网 IP。",[11,221,222,223,228],{},"参见 [STUN 的工作机制][",[125,224,227],{"href":225,"rel":226},"https:\u002F\u002Fbloggeek.me\u002Fgoogle-free-turn-server\u002F",[129],"how-does-stun-work","] 一文。",[11,230,231,232],{},"￼￼",[56,233],{"alt":234,"src":235},"STUN server","https:\u002F\u002Fblog.phuaxueyong.com\u002Fimg\u002F2020-06-15-how-to-make-a-video-chat-app\u002Fstun.png",[11,237,238],{},"如你所见，浏览器向 STUN 服务器请求公网 IP 信息。这一过程隐于幕后，用户不会感知到。不过我学到的一点是永远不会有真正的魔法，幕后发生了很多事情。如果你想要了解魔法，那么你需要了解幕后的这些步骤。",[114,240,77],{"id":241},"_4-turn-服务器的作用是什么",[11,243,244],{},"中继穿透 NAT（Traversal Using Relay NAT）是一种网络流量中继协议。有时通过 STUN 服务器能够成功获取远程成员的公网 IP，但是因为防火墙、NAT 等网络相关工具的原因，需要可以在公网访问到的 TURN 服务器进行中继。TURN 服务器有点像是传递消息的中间人。",[11,246,247,248],{},"￼",[56,249],{"alt":250,"src":251},"Turn server","https:\u002F\u002Fblog.phuaxueyong.com\u002Fimg\u002F2020-06-15-how-to-make-a-video-chat-app\u002Fturn.png",[111,253],{},[114,255,257],{"id":256},"_5-如何扩容值得考虑的四种主要架构","5. 如何扩容？值得考虑的四种主要架构！",[46,259,260],{"id":260},"网状",[11,262,263],{},"在网状网络（Mesh）架构下，成员之间两两连接，比如一个电话会议有三个成员，每条消息都需要加密、传输两次。",[46,265,266],{"id":266},"转发",[11,268,269,270,274],{},"选择性转发单元（Selective Forwarding Unit，SFU）位于会话的中心，智能地中继媒体。假设共有 n 个客户端，每个客户端需要和 SFU 建立一条上行连接用于上传媒体数据，以及 n - 1 条下行链接用于接收其他客户端的媒体数据。虽然这种架构需要的总连接数是 ",[271,272,273],"code",{},"n ** 2","，但每个客户端只需建立一条加密的上行链接，这就减轻了设备本身的带宽压力，这对移动设备而言尤其重要（移动网络的上行带宽更小）。",[11,276,277],{},"转发需要 SFU 这类额外的服务器基础设施，不过 SFU 能够高效地处理任务。这是因为除非需要录制视频，SFU 不用解密数据包，也不用解码数据。",[46,279,280],{"id":280},"混合",[11,282,283],{},"这一架构需要一个多点控制单元（Multipoint Control Unit，MCU）在会话中充当强力的媒体混合器。每个客户端和 MCU 建立一个连接。不管总共有多少客户端，每个客户端都只需要处理一个向 MCU 发送数据并从 MCU 接收数据的双向连接。",[11,285,286],{},"和转发架构类似，发送媒体数据只需要加密、上传一次，不同的是接收媒体数据也需要下载和解密一次。这种方式对客户端而言最高效，但对服务器而言最低效。解包、解码、混合、编码、打包都在服务器上进行。服务器需要大量资源完成这么多实时操作。",[11,288,289],{},"混合架构适用于有大量活跃参与者的应用场景，比如虚拟教室，以及设备资源限制比较紧张的应用场景，比如设备的带宽很有限。这一架构下服务器的开销很大。",[46,291,292],{"id":292},"组合",[11,294,295],{},"顾名思义，组合使用多种架构，根据具体情况为参与者创建会话。",[147,297,298,301,304],{},[27,299,300],{},"简单的双方通话，采用网状架构，这一架构最简单，需要的服务器资源最少。",[27,302,303],{},"小型群聊、直播、在线活动，采用转发架构。",[27,305,306],{},"大型群聊、虚拟互动，混合架构值得考虑。",[114,308,310],{"id":309},"_6-如何使用-testrtc-测试-webrtc-应用","6. 如何使用 [Testrtc] 测试 WebRTC 应用？",[11,312,313],{},"WebRTC 应用比较容易发生规模问题，因为它需要处理大量数据。所以如果你打算给 WebRTC 应用扩容，首先要考虑的就是采用合适的架构，其次要考虑数据流量问题。",[11,315,316],{},"我进行的压力测试中，共有 500 个参与者，分为多个聊天室，每个聊天室有 5 个成员，应用只撑了 6.5 分钟。在不到 10 分钟的时间内，服务器实际传输了 52 GB 的上下行数据。",[11,318,319],{},[125,320,323],{"href":321,"rel":322},"https:\u002F\u002Ftestrtc.com\u002F",[129],"Testrtc",[114,325,327],{"id":326},"_6b-资源","6b. 资源",[11,329,330],{},"开发实现自己的 WebRTC 应用时，你可以试用以下的免费 STUN 服务器：",[11,332,333],{},[125,334,337],{"href":335,"rel":336},"https:\u002F\u002Ffree-for.dev\u002F#\u002F?id=stun-webrtc-web-socket-servers-and-other-routers",[129],"免费 STUN 服务器",[11,339,340],{},"我找到了一个比较全面的讲解 WebRTC 应用工作机制的 YouTube 视频。有意思的是，我发现所有 YouTube 上 WebRTC 视频都是几年前的。WebRTC 已经有 7 年的历史了。我 Joshua 终于赶上了，希望文章有助于你了解这个古老的技术。(:",[34,342,344],{"className":343},[37],[39,345],{"src":346,"frameBorder":42,"allow":43,"allowFullScreen":44},"https:\u002F\u002Fwww.youtube.com\u002Fembed\u002F2Z2PDsqgJP8",[111,348],{},[11,350,351],{},"参考资料：",[147,353,354,361,368,375,382,389,396],{},[27,355,356],{},[125,357,360],{"href":358,"rel":359},"https:\u002F\u002Fwebrtc.org\u002Fgetting-started\u002Fturn-server",[129],"What is a TURN server",[27,362,363],{},[125,364,367],{"href":365,"rel":366},"https:\u002F\u002Fwww.ably.io\u002Fblog\u002Fsolving-the-webrtc-signalling-challenge\u002F",[129],"The signalling challenge",[27,369,370],{},[125,371,374],{"href":372,"rel":373},"https:\u002F\u002Fwww.frozenmountain.com\u002Fdevelopers\u002Fblog\u002Farchive\u002Fhow-to-successfully-scale-your-webrtc-application\u002F",[129],"Scale your webrtc application",[27,376,377],{},[125,378,381],{"href":379,"rel":380},"https:\u002F\u002Fbloggeek.me\u002Fmistakes-developing-webrtc-applications\u002F",[129],"5 mistakes to avoid developing webrtc applications",[27,383,384],{},[125,385,388],{"href":386,"rel":387},"https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=nfF2i8Bnqoo",[129],"Webinar for WebRTC",[27,390,391],{},[125,392,395],{"href":393,"rel":394},"https:\u002F\u002Fjitsi.org\u002Fjitsi-videobridge\u002F",[129],"jitsi.org videobridge",[27,397,398],{},[125,399,402],{"href":400,"rel":401},"https:\u002F\u002Fwww.html5rocks.com\u002Fen\u002Ftutorials\u002Fwebrtc\u002Finfrastructure\u002F",[129],"Webrtc Infrastructure",{"title":58,"searchDepth":404,"depth":405,"links":406},2,3,[407,408,409,415,416,417,423,424],{"id":48,"depth":405,"text":49},{"id":116,"depth":404,"text":117},{"id":176,"depth":404,"text":49,"children":410},[411,412,413,414],{"id":179,"depth":405,"text":180},{"id":189,"depth":405,"text":190},{"id":199,"depth":405,"text":200},{"id":206,"depth":405,"text":207},{"id":213,"depth":404,"text":69},{"id":241,"depth":404,"text":77},{"id":256,"depth":404,"text":257,"children":418},[419,420,421,422],{"id":260,"depth":405,"text":260},{"id":266,"depth":405,"text":266},{"id":280,"depth":405,"text":280},{"id":292,"depth":405,"text":292},{"id":309,"depth":404,"text":310},{"id":326,"depth":404,"text":327},null,"2020-06-15","WebRTC 简明教程，介绍了 WebRTC 的工作机制和常见架构","常见的视频应用利用了一种叫做 WebRTC 的技术。WebRTC 让开发者能够基于 web 交换数据和媒体文件的应用，可以用于大家日常使用的浏览器。这是近十年来发生的技术转变，过去只能通过 flash 之类的插件实现这一功能。 即使你没听说过 WebRTC，你多半已经用过它了。Whatapps、Facebook、Google…","md","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1585974738771-84483dd9f89f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1266&q=80","zh-sg",{"layout":433,"fig-caption":425,"tags":434},"post",[435],"100DaysToOffload，地址，应用程序，体系结构，客户端，连接，数据，信息，媒体，服务器，会话，信令，sun，已使用，web，webrtc","\u002Fposts\u002Fzh-sg\u002F2020-06-15-how-to-make-a-video-chat-app",8,{"title":6,"description":427},"2020-06-15-how-to-make-a-video-chat-app","posts\u002Fzh-sg\u002F2020-06-15-how-to-make-a-video-chat-app",[442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457],"100DaysToOffload","地址","应用程序","体系结构","客户端","连接","数据","信息","媒体","服务器","会话","信令","sun","已使用","web","webrtc","fp_uqvHvuu5L3vGUl06wUYk_-TPCUhDiru5ySYtkQyU",1794023764450]