范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

WebRTC成为HTML5标准?SDPSTUNTURN你想知道的都在这里!

  大家好,很高兴又见面了,我是"web 前端分享",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!
  上一篇文章《WebRTC已成为HTML5标准?是时候开始学习了?》发布后反响不错,特定再出一文详细论述WebRTC、SDP、STUN、TURN等诸多内容,创作不易,拒绝转发到其他平台,万望理解!1.前言1.1 什么是 WebRTC?
  下图展示了不同协议出现的时间线:
  各传输协议时间线
  在计算机网络中,协议是一组规则,用于管理数据在设备之间的交换方式。 协议定义了通信的规则、语法、语义和同步以及可能的错误恢复方法,本文中讨论的 WebRTC 协议定义了应用层软件如何相互交互。
  WebRTC(Web Real-Time Communication)也被称为网络实时通信,是由 Google、Mozilla 和其他公司推动的一个开源项目,它通过 Javascript API 实现无插件的实时通信,建立浏览器之间点对点(Peer-to-Peer)的连接。 1.2 WebRTC 的优点?
  WebRTC 的优点可以归纳为以下几个方面: 开源、免费,开发者不需要承担高昂的专利费用 基于浏览器,不需要安装插件,只要调用 API 就可以实现音视频互动 被纳入了 HTML5 标准,主流浏览器全面支持 WebRTC 不仅支持 Web 之间的音视频通讯,还支持 Android 以及 IOS 端,由于该项目是开源的,我们也可以通过编译 C++代码,从而达到全平台的互通
  在 WebRTC 诞生之前,开发实时音视频应用的成本是非常高,需要考虑的技术问题很多,如音视频的编解码, 数据传输延时、丢包、网络抖动、回音处理和消除 等,如果要兼容浏览器端的实时音视频通信,还需要额外安装插件。可喜的是,本文的主角 WebRTC 在 2021 年 1 月被 W3C 和 IETF 发布为正式标准,而且得到了大多数主流浏览器的支持。
  CanIUse 中 WebRTC 的浏览器支持情况
  WebRTC 项目的愿景:实时通信 web 化,让 WebRTC 成为互联网音视频实时通信的规范,让开发者基于此规范快速开发出安全、可靠的应用。WebRTC 必须在 HTTPS 环境下运行,你可以在https://appr.tc/、https://snapdrop.net/体验WebRTC应用,或者在https://nashaofu.github.io/webrtc-demo/,https://webrtc.github.io/samples/查看WebRTC示例。 2.了解SDP和Offer-Answer模型2.1 什么是RTP/RTCP?
  大多数人已经了解 TCP 和 UDP 等传输协议,当您要保证传输数据准确(例如:邮件)时,TCP 协议更好,而 UDP则更加偏向传输速度(例如:YouTube 视频)。
  实时传输协议 (Real-time Transport Protocol,RTP) 又是一种用于通过 IP 网络传送音频和视频的网络协议。 RTP 广泛用于涉及流媒体的通信和娱乐系统,例如电话、视频电话会议、电视服务等。 作为一种电信标准,WebRTC 正在使用 RTP 传输实时数据。
  RTP 控制协议 (RTP Control Protocol ,即RTCP) 是实时传输协议 (RTP) 的兄弟协议。 RTCP 为 RTP 会话提供额外统计和控制信息。 使用 RTCP您可以获得有关数据传输成功的数据,例如"传输过程中发生了多少数据包丢失"、"数据包延迟是多少"或"视频通话的分辨率是多少"等等。
  RTP 和 RTCP 数据包的传输发生在媒体通道上,而WebRTC 负责媒体通道上的媒体传输。作为应用程序开发人员,您的责任是管理信令通道。 所以你通常不知道这些概念,而且大多数时候你不需要它们,但在开始 SDP 和 Offer-Answer 模型之前有必要先了解下 RTP/RTCP 。2.2 什么是SDP(Session Description Protocol)?
  现实生活中,如果您想让人们联系到您,您会分享您的联系信息,比如电子邮件、电话号码、Instagram 帐户、家庭住址等。 分享此类信息的最简单方法是向他们提供您的名片,而为了能够找到对方, 互联网数字名片可能包含以下信息:主叫方和被叫方IP 地址支持哪些媒体类型(音频、视频、屏幕共享等)当前启用或禁用了哪些媒体类型(视频开/关保持/取消保持等)对方都支持哪些编解码器类型
  互联网数字名片
  在电信领域,称这种数字名片为会话描述协议 (SDP), SDP 包含对等点相互交谈所需的信息。WebRTC 也使用 SDP 作为通信标准来发起呼叫, SDP 只是一个可以被端点解析和操作的文本。
  例如,如果用户想要保持通话,您可以通过将 SDP 作为应用程序进行操作来禁用/启用视频和音频流。 或者您的系统需要特定的视频编解码器,比方说 H.264,您可以删除除 H.264 之外的任何其他编解码器。
  这就是 SDP 的强大之处,它很容易根据您的要求进行操作
  下面是一个 SDP 示例,可能包含以下信息:o=alice 2890844526 2890844526 IN IP4 10.48.1.2 //O=表示呼叫的发起者、会话ID和发起者的IP地址 t=0 0 //t= 表示会话结束时间。如果为 0,则表示会话不受时间限制 m=audio 49170 UDP/TLS/RTP/SAVPF 111 0 // m=表示media line,是session中可以存在的媒体属性。 在这种情况下,它表示音频媒体线。 此行还包含将在会话中使用的传输协议 (UDP/TLS/RTP/SAVPF)。 最后,此行包含将在会话中使用的编解码器有效载荷编号 (111, 0) c=IN IP4 217.345.789.123 // c=表示连接信息,比如你要调用的远程设备的IP地址 a=sendrecv a=rtpmap:111 opus/48000/2 a=rtpmap:0 PCMU/8000 //a= 表示属性线。 它定义会话和媒体行属性。 在第一行中,a=sendrcv 属性表示设备愿意发送和接收音频媒体,他还 可以有其他值,如 recvonly、sendonly 或 inactive用于不同的场景,如保持或视频关闭 // Rtpmap 属性指示音频编解码器编号的映射。 在这种情况下,111 映射到具有 48,000 bps 带宽的 Opus,而 0 映射到具有 8,000 bps 带宽的 PCMU 编解码器, 标准 SDP 中可以有更多的属性行。 m=video 51372 UDP/TLS/RTP/SAVPF 98 100 //m= 也表示媒体行,在这种情况下,它表示视频媒体线。同样,它包含传输协议和编解码器有效负载编号。 a=sendrecv a=rtpmap:98 VP9/90000 a=rtpmap:100 H264/90000 //a= 表示属性行。 在第一行中,a=sendrcv 属性表示设备愿意发送和接收视频媒体 //rtpmap 值,98 映射到具有 90,000 bps 带宽的 VP9 视频编解码器,100 映射到具有 90,000 bps 带宽的 H.264 视频编解码器
  SDP的更多属性配置可以阅读文末资料,这里不再展开。2.3 什么是Offer-Answer模型?
  到目前为止,解释了"WebRTC 如何在媒体通道中传输数据?"(RTP/RTCP)和"如何在信令通道中根据需要指定会话属性?"(SDP)。 接下来回答"应用程序应该如何相互传输会话属性 (SDP)?"。
  你可能有一张华丽的名片,但如果你不把它送给任何人,它就毫无用处, 此规则也适用于 SDP。 我们需要在对等点之间交换 SDP 以发起呼叫。 Offer-Answer 模型是在 WebRTC 中用作电信标准的 SDP 交换过程,交换方式由申请时决定。 应用程序可以通过 HTTP/HTTPS 请求、Web 套接字、推送通知等方式发送它。这完全取决于应用程序。
  Offer-Answer模型
  Offer-Answer模型顾名思义,在这个模型中有一个 Offerer 和一个 Answerer。 提供者是启动信令过程的人,例如开始拨出电话或发送通话事件的人,包括保持和关闭视频开关。 回答者是回答传入提议的人, 例如接听来电或向通话中事件发送合适的数据。
  Offer-Answer 模型有 4 个基本步骤;Offerer 创建一个 Offer SDP 并将其发送到远程节点。应答者收到提议者的 SDP,并自行设置。Answerer 创建一个 Answer SDP 并将其发送给 offerer提供者收到应答者的 SDP,并自行设置。
  之后,如果一切正常,呼叫开始。2.4 WebRTC的Offer-Answer模型交换流程
  下图显示了 WebRTC 上使用 Offer-Answer 模型的 SDP( Session Description Protocol,即会话描述协议) 交换过程:
  WebRTC 信令流程
  接下来一一说明这些步骤: Peer-1 获取用户媒体,然后从 WebRTC 创建一个 PeerConnection 对象 创建PeerConnection后,应用程序需要调用WebRTC的createOffer接口 WebRTC 创建一个Offer SDP ,并且可以根据需要操作 SDP 应用程序应将 Offer SDP 设置回 WebRTC 应用程序应向 Peer-2 发送Offer SDP Peer-2 上的应用程序收到Offer SDP, Peer-2 应该获取用户媒体并创建 PeerConnection 对象(如果目前尚未创建) Peer-2 上的应用程序将Offer SDP 设置给 WebRTC Peer-2 上的应用程序使用 WebRTC 的 createAnswer API 生成应答 SDP WebRTC 创建一个应答 SDP 并将其提供给应用程序,应用程序可以根据需要操作SDP 应用程序应将 Answer SDP 设置给 WebRTC Peer-2 上的应用程序应将应答 SDP 发送给 Peer-1 Peer-1 上的应用程序设置应答 SDP 如果一切正常,RTP 媒体流将通过 WebRTC 在媒体通道上启动。
  上面可能有很多步骤,但其中大部分都是重复性任务。 WebRTC 交换 offer 与网络参数之后,就会尝试直接使用对方的 IP 地址与端口进行直连,这个过程会根据双方网络情况,使用的不同的方式建立连接,后文 NAT(Network Address Translation,即网络地址转换)打洞就是介绍这部分内容。 3.什么是信令服务器?什么是STUN?什么是TURN?
  A 与 B 在建立 WebRTC 连接过程中,需要互相知道对方的 IP 与通信端口。那么 A 与 B 要如何知道对方的 IP 与端口呢?答案就是通过信令服务器。 信令服务器的作用是作为一个中间人帮助双方在尽可能少的暴露隐私的情况下建立连接。WebRTC 并没有提供信令传递机制,你可以使用任何方式如 WebSocket 或者 XMLHttpRequest 等,来交换彼此的令牌信息。
  STUN 和 TURN 服务器是两种类型的 WebRTC 信令服务器,可用于在构建实时通信应用程序时创建对等 (P2P) 连接。 3.1 什么是STUN?
  STUN(NAT 会话遍历实用程序)使用 UDP 协议通过 NAT 来实现 ICE能力。 STUN 允许应用程序发现它们之间和公共互联网上的 NAT 、防火墙的存在和类型。 任何设备都可以使用它来确定 NAT 分配给它的 IP 地址和端口。
  通常,STUN 客户端可以向 STUN 服务器发送消息以获取公共 IP 和端口信息,然后基于此公共 IP 和端口信息即可在客户端之间通过互联网进行点对点通信。3.2 什么是TURN?
  TURN(Traversal Using Relays around NAT)是一种协议,可协助 webRTC 应用程序穿越网络地址转换器 (NAT) 或防火墙。 TURN Server 允许客户端通过中间服务器发送和接收数据, TURN 协议是 STUN 的扩展。
  在少数情况下,客户端通信端点在不同类型的 NAT 后面,或者当使用对称 NAT 时,通过中继服务器及其称为 TURN 服务器发送媒体可能更容易。4.WebRTC API 调用4.1 RTCPeerConnection
  RTCPeerConnection 用于点对点之间建立连接以传输音视频数据流,这是 RTCPeerConnection 的任务,为此需要借助一个信令服务器(signaling server)来进行,信令包括 3 种类型的信息: Session control messages: 初始化和关闭通信,及报告错误; Network configuration: 双方的 IP 地址和端口号(局域网内部 IP 地址需转换为外部的 IP 地址); Media capabilities: 双方的浏览器支持使用何种编码以及多高的视频分辨率。  var PeerConnection =   window.RTCPeerConnection ||   window.mozRTCPeerConnection ||   window.webkitRTCPeerConnection; navigator.getUserMedia = navigator.getUserMedia   ? "getUserMedia"   : navigator.mozGetUserMedia   ? "mozGetUserMedia"   : navigator.webkitGetUserMedia   ? "webkitGetUserMedia"   : "getUserMedia"; var v = document.createElement("video"); // 创建信令(createOffer) var pc = new PeerConnection(); pc.addStream(video); pc.createOffer(function (desc) {   pc.setLocalDescription(desc, function () {     // send the offer to a server that can negotiate with a remote client   }); }); // 创建回复(createAnswer) var pc = new PeerConnection(); pc.setRemoteDescription(new RTCSessionDescription(offer), function () {   pc.createAnswer(function (answer) {     pc.setLocalDescription(answer, function () {       // send the answer to the remote connection     });   }); });4.2 RTCDataChannel
  RTCDataChannel 接口代表在两者之间建立了一个双向数据通道的连接,可以用 RTCPeerConnection.createDataChannel() 或者在现有的 RTCPeerConnection 上用 RTCDataChannelEvent 类型的 datachannel 事件接收,创建出 RTCDataChannel 类型的对象。  var pc = new RTCPeerConnection(); // 获取 RTCPeerConnection 对象 var dc = pc.createDataChannel("my channel"); // 创建 DataChannel 对象 dc.onmessage = function (event) {   console.log("received: " + event.data); }; dc.onopen = function () {   console.log("datachannel open"); }; dc.onclose = function () {   console.log("datachannel close"); };4.3 访问用户摄像头及麦克风 getUserMedia
  WebRTC 支持直接传输音频流和视频流(https://appr.tc/):  const pc = new RTCPeerConnection() ; // 获取RTCPeerConnection navigator.getUserMedia({ video: true }, stream => {    // 添加视频流到会话中   stream.getTracks().forEach(track => pc.addTrack(track, stream))    // 在网页中预览自己摄像头拍摄到的内容,其中$localVideo表示一个Video对象   $localVideo.srcObject = stream;  })
  navigator.getUserMedia()还可以和web Audio API相结合,用来处理音频效果: var range = document.querySelector("input"); window.AudioContext = window.AudioContext || window.webkitAudioContext; var audioCtx = new AudioContext(); navigator.getUserMedia({     audio: true }, function(stream) {     // 创建音频流     var source = audioCtx.createMediaStreamSource(stream);     // 双二阶滤波器     var biquadFilter = audioCtx.createBiquadFilter();     biquadFilter.type = "lowshelf";     biquadFilter.frequenc.value = 1000;     biquadFilter.gain.value = range.value;     source.connect(biquadFilter);     biquadFilter.connect(audioCtx.destination); }, function(error) {     console.log(error); });
  其实,WebRTC并不只是用来做视频、音频,它还可以用来传输任意数据,包括文件,文本等。上面代码示例可以看到,WebRTC规定了 dataChannel 这个双工数据通道,而https://snapdrop.net/这个网站就是通过WebRTC进行文件分享。 const pc = new RTCPeerConnection()  const dataChannel = pc.createDataChannel("chat")  // 监听datachannel事件 pc.addEventListener("datachannel", event => {    // 接收通信方发送过来的数据   event.channel.addEventListener("message", event => {      console.log("message", event.message)    })  })  dataChannel.addEventListener("open", () => {    // 发送数据,可发送任意数据    dataChannel.send("Hi!")  })  dataChannel.addEventListener("close", event => {  }) 4.4 candidate 事件
  当 RTCPeerConnection 实例执行 setLocalDescription()后,RTCPeerConnection 就会探测自己的网络环境,然后用 candidate 事件返回候选网络环境数据,网络环境数据中最重要的是 IP 地址与端口组成的候选通信地址。 candidate 事件中的 event.candidate 主要包含以下几个部分: 本机 IP 地址 本机用于 WebRTC 通信的端口号 候选者类型,包括 host、srflx 和 relay 优先级 传输协议
  具体数据结构的示例如下: {   address: "192.168.31.67",   candidate:     "candidate:2147606101 1 udp 2122260223 192.168.31.67 57959 typ host generation 0 ufrag EaWw network-id 1 network-cost 10",   component: "rtp",   foundation: "2147606101",   port: 57959,   priority: 2122260223,   protocol: "udp",   relatedAddress: null,   relatedPort: null,   sdpMLineIndex: 0,   sdpMid: "0",   tcpType: null,   type: "host",   usernameFragment: "EaWw", };
  candidate 事件 type 字段取值分别为 host、srflx、relay: host(Host candidate) :从本地网卡上获取的地址 srflx(Server reflexive candidate) :STUN(Session Traversal Utilities for NAT,即 NAT 会话穿越应用程序) 返回的该客户端的地址 relay(Relay reflexive candidate): :TURN (Traversal Using Relay NAT,即通过 Relay 方式穿越 NAT)服务器为该客户端分配的中继地址
  本地的 candidate 与远端 candidate 构成的每一对都有一定的优先级,按优先级排序进行连通性检查。最后从有效的 candidate 组合中选择优先级最高的作为传输地址,用于建立 P2P 连接。 5.网络地址转换(NAT)
  网络地址转换(英语:Network Address Translation,缩写:NAT;又称网络掩蔽、IP 掩蔽)在计算机网络中是一种在 IP 数据包通过路由器或防火墙时重写来源 IP 地址或目的 IP 地址的技术。这种技术被普遍使用在有多台主机但只通过一个公有 IP 地址访问互联网的私有网络中。 要建立一个连接需要知道对方的 IP 地址和端口号,在局域网里面一台路由器(基站)可能会连接着很多台设备,例如家庭路由器接入宽带的时候,宽带服务商会分配一个公网的 IP 地址,所有连到这个路由器的设备都共用这个公网 IP 地址。如果两台设备都用了同一个公网 IP:port 去发送请求,服务器返回数据在经过路由器时它就不知道应该转发给哪一个设备。因此路由器需要重写 IP 地址/端口号进行区分,如下图所示:
  NAT 设备通常会自动设置各个设备的映射关系,也可以在路由器端去手动设置。如上图的 NAT 维护的映射关系还会和要访问的目标 IP 地址进行绑定,例如同一终端使用同一端口访问不同的目标 IP,就会建立不同的映射关系。
  如上示例 NAT 上建立的映射关系如下:
  内网 IP 端口
  外网 IP 端口
  NAT 对外 IP 与端口
  192.168.1.2:8080
  39.182.39.30:443
  10.188.20.10:8000
  192.168.1.2:8080
  39.182.39.40:443
  10.188.20.10:8001
  所以实际存储的映射关系会包含上面 3 部分内容,这样做的目的是保证网络安全。想象如下例子,终端 192.168.1.2:8080 通过路由器使用 10.188.20.10:8000 访问服务器 A,建立 NAT 映射如果为 192.168.1.2:8080-->10.188.20.10:8000,那么如果有人向 10.188.20.10:8000 发送数据就会转发到 192.168.1.2:8080,这样就会导致内网的服务被外部随意访问,所以 NAT 映射会记录目标地址。当然,由于 NAT 有多种类型,NAT 映射也会存不同,更多内容可参考维基百科或者 WebRTC 网络基础 九、第二节 NAT 打洞原理,下表进行一个简单的归纳。
  5.1 NAT 打洞
  由于 NAT 有上面 4 种类型,所以两个设备要建立 P2P 连接就要使用不同的方式。 5.1.1 完全锥型 NAT
  完全锥型是非常简单的 ,左边是内网的主机,它有自己的内网 IP 地址和端口 ,通过防火墙之后,它形成一个外网的 IP 地址,那么外网的主机要想与内网的主机进行通信的时候,首先要由内网的主机向外发送一个请求,请求外网中的其中一台主机,这样会形成的结果就是它会在 NAT 服务上打一个洞,这样会形成一个外网的 IP 地址和端口。 形成了外网的 IP 地址和端口之后, 其他的主机只要获得了这个 IP 地址和端口它都可以向它发送数据 。并且可以顺利的通过防火墙发送给内网的主机。这样就可以进行通讯了,这是完全锥型,也是最好穿越的一种 NAT 类型。但是安全性就差很多。
  NAT内网计算机IP地址为10.0.0.1,其在端口 8000 上收发消息,映射到 NAT 上的外部IP和端口为 202.123.211.25:8000。 这样Internet 上的任何人都可以向 NAT 上的内网 IP: 端口发送数据包,这些数据包将被传递到 10.0.0.1:8000 的客户端机器。5.1.2 地址限制锥型 NAT
  它的安全性好一些,它会在防火墙上形成一个 五元组 ,即内网主机的 IP 地址和端口、映射后的公网 IP 地址和端口、请求的主机 IP 地址。他们首先有一个公共的步骤,第一步就是要先由内网的主机向外网发送一个请求,在这个防火墙上或者 NAT 服务上形成一个映射表,那形成之后外网的主机就可以和内网的主机进行通讯了。
  客户端向服务器 1(IP - 192.248.22.100)发送数据包,然后NAT将客户端的10.0.0.1:8000映射到外网的202.123.211.25:8000, 现在 server1 可以将数据包发送到目的地。 但是,NAT 将阻止来自服务器 2(IP - 192.248.22.200)的数据包,直到客户端向服务器 2 的 IP 地址发送数据包。 一旦客户端将数据包发送到服务器 2,服务器 1 和服务器 2 都可以将数据包发送回客户端。5.1.3 端口限制锥型 NAT
  端口限制型就更加严格一些了,不光是对 IP 地址,还要对端口做限制,所以在防火墙上就形成了 六元组 ,不光有内网的 IP 地址和端口、映射后的公网的 IP 地址和端口、还有你请求的主机的 IP 地址和端口。
  如果客户端将数据包发送到 192.248.22.100:10100(包含IP 和端口),NAT 将只允许来自 192.248.22.131:10100 的数据包(到客户端),它 丢弃 来自 192.248.22.131:10200(相同 ip 但不同端口)的数据包。 5.1.4 对称型 NAT
  对称限制型就更加严格了,以前的类型是在防火墙上形成映射后的公网的 IP 地址是保持不变的,大家要找还是能找到它的,虽然不通,但是对于 这个对称型它就不一样了,它就发生了变化,不光是形成了一个 IP 地址和端口,而且还会形成多个, 对于每一台主机都会形成一个不同的 IP 地址和端口对 。
  如果客户端从 10.0.0.1:8000 发送数据到 server1,其外网地址被映射为 202.123.211.25:12345,而如果客户端从同一个端口(10.0.0.1:8000)发送到不同的 IP,则映射的外网地址也会不同(即外网地址被映射为 202.123.211.25:45678)。  server1 只能响应自己的映射,server2也 只能响应自己的映射,两者无法公用 。 如果任何一个地址尝试发送到另一个映射的 IP:port,这些数据包将被丢弃。 5.2 WebRTC 打洞这么复杂么?
  WebRTC 本身就已经实现 NAT 打洞功能,只需要连接的双方交换了网络端口和 IP 之后,WebRTC 就会自动进行打洞。WebRTC 使用一个叫做交互式连接设施( ICE,Interactive Connectivity Establishment,即交互式连接建立 )协议框架,ICE 整合了 STUN 与 TURN。STUN 是用来探测终端 NAT 类型、IP 和端口的服务,WebRTC 获取到 NAT 类型、IP 和端口后就会触发 candidate 事件,然后连接双方交换 IP 与端口,开始打洞。如果打洞失败,那么就会使用 TURN 服务器转发流量。
  由于 WebRTC 提供了 ICE,所以使用非常简单,只需在 new RTCPeerConnection 时传入 iceServers 参数即可。googel 提供了免费的 STUN 服务器去帮助打洞,也可以自己架设服务器。 const pc = new RTCPeerConnection({   // 可以传入多个 stun 服务器或者 turn 服务器   iceServers: [     { url: "stun:stun.l.google.com:19302" },     { url: "stun:stun1.l.google.com:19302" },     { url: "stun:stun2.l.google.com:19302" },     { url: "stun:stun3.l.google.com:19302" },     { url: "stun:stun4.l.google.com:19302" },   ], });6.WebRTC vs WebSocket 区别用途区别 WebSocket允许浏览器和Web服务器之间进行全双工通信. WebRTC允许两个浏览器之间的全双工通信。
  2. 协议区别 WebSocket使用TCP协议 WebRTC使用UDP协议
  3. 流量路径 WebSocket浏览需要经过服务器 WebRTC是直接连接,浏览不会经过第三方服务器,是一个去中心化的架构模型,简单说就是省带宽。
  4. 实时性 WebSocket延迟高(不是直接连接) WebRTC延迟低
  通常WebRTC会与WebSocket配合使用,WebSocket的作用主要是用来交换客户端的SDP与网络信息,Websocket传输的内容与真正通信数据无关,只是协助WebRTC建立连接。参考资料
  https://medium.com/orion-innovation-turkey/webrtc-in-a-nutshell-ep-ii-ca8cb33f8ff3
  https://datatracker.ietf.org/doc/html/rfc4566
  https://medium.com/rahasak/network-address-translation-nat-df84dc1cb06c
  https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel
  https://caniuse.com/?search=WebRTC
  https://www.jianshu.com/p/1022f559a805
  https://zhuanlan.zhihu.com/p/421503695
  https://github.com/nashaofu/webrtc-demo
  https://blog.csdn.net/xyphf/article/details/107297616
  https://medium.com/av-transcode/what-is-webrtc-and-how-to-setup-stun-turn-server-for-webrtc-communication-63314728b9d0
  https://webrtc.ventures/2020/12/webrtc-signaling-stun-vs-turn/

盘点5款性价比超高的白酒,滴滴纯粮酿造,可惜很多人都还没喝全盘点5款性价比超高的白酒,滴滴纯粮酿造,可惜很多人都还没喝全过随着人们对酒的需求日益增加,白酒产业得到了蓬勃发展,成就了当下白酒遍地开花的局面。如今国内的白酒被分为12种香型,而各冬天给宝宝做这件事,真的很重要冬天一到,家长们都不约而同进入警戒状态,使出浑身解数保护宝宝不受寒冷干燥流感的威胁。但是其实家长们厚重的爱往往在不知不觉间给宝宝带来了一定的负担,看似有道理的方式不一定对哦加湿器开一生一会在我半个世纪的人生中,有三个眼神,也就是三个瞬间,来自素不相识的陌生人,每每想起,让我动容,让我感到也曾被这薄凉的世界温柔以待。第一次,刚生完老大,我极度虚弱地躺在医院的病床上,两110月高技术产业实际使用外资快速增长央广网北京11月26日消息据国家发改委网站25日消息,据相关部门统计数据显示,今年110月高技术产业实际使用外资(按可比口径)同比增长31。7,增速高于全国实际使用外资增速17。3讲好红色故事,彰显红色魅力仁和云会红风情小镇一项目背景顺应国家战略,紧跟时代步伐。将云会村以工商贸易为主,农林牧副渔为辅,欲打造成为集红色记忆乡村体验为一体的云会红风情小镇。二设计说明特色突出主题鲜明。云会村红色文化突出,有一文读懂中国农业产业概况报告核心观点1。从产值来看国家统计局数据显示,2010年以来,全国农林牧渔业总产值以及细分的农业总产值林业总产值渔业总产值持续正增长,牧业总产值则波动明显整体呈先增后降趋势。其中,并购优塾新能源车系列,大型压铸机产业链跟踪力劲科技VS伊之密微信公众号并购优塾(moneyC2C)首发,更多文章可微信关注我们的公众号并购优塾产业链地图压铸机的本质需求是什么?压铸的需求来自金属成型,按金属成型前形态,可以分为粉末成型液态成淄博的聊斋文化产业如何发展?请您来提建议淄博是聊斋文化的发源地,是聊斋故里,是世界短篇小说之王蒲松龄的故乡,蒲老先生为淄博人留下来宝贵的文化遗产。聊斋志异以及聊斋文化在中国古典文化浩瀚的历史长河中烨烨生辉,而且独树一帜,关于亲子阅读,分享一篇我以前给家乡图书馆写的宣传稿这篇文章是我本人在家乡(浙江省丽水市缙云县)图书馆工作的时候写的(小小临时工,负责宣传稿写作,嘻嘻),题材来自于一场亲子阅读讲座。想要了解更多亲子阅读知识的小伙伴们可以去阅读一下朱孔家坊乡中心幼儿园古韵幽香,诗词满员园比赛活动古诗词是我国文学宝库中的一颗璀璨明珠,感情真挚韵律感极强。天生我材必有用,千金散尽还复来一千两百多年前的诗句,今天读来,依然让人血脉偾张。诗人笔下喷涌而出的跌宕起伏的情感,让我们感从萧蔷陈德容,到后期的林心如谁才是真正的台湾女神?在二三十年前,港台明星在内地相当的有排面。一众明星,来到内地大把捞金。而内地粉丝们也是追捧在她们身后。今天我们就来盘点一下出现过的女神。陈德容陈德容出名还是因为琼瑶剧,电影很少参与
甜味剂龙头,2022年净利润增超40头条创作挑战赛安徽金禾实业股份有限公司主营业务为食品添加剂产品主要包括甜味剂和香料产品。公司生产的安赛蜜和三氯蔗糖属于第四代,第五代高倍甜味剂均具有无能量甜度高口感纯正安全性高等特乔恩贝特曼不给中美脱钩踩刹车,美国自己会摔下悬崖文乔恩贝特曼几乎没有经过大张旗鼓或公开辩论,美国就进入了堪称冷战以来最困难和最危险的国际挑战。这个挑战是,经过数十年来与中国的经济和技术一体化,美国现在将中国看成主要竞争对手,想扭净利大跌82。13!韦尔股份将计提14。9亿元存货跌价准备!1月13日晚间,国产图像传感器龙头大厂韦尔股份发布2022年年度业绩预减公告,预计2022年度实现归属于上市公司股东的净利润为8亿12亿元,同比大幅下降73。1982。13预计实现基金你这么办,牛市里也挣不了钱今天看了你早上的发文,以为你新冠阳第三次了,吓我一跳。今年这几个交易日你收益满满啊,为你高兴,我投资的六十多万,去年亏了19,十三万多。今年到昨天为止扭亏六万多,现在还亏四万多,唉税控盘及税务UKEY开票软件升级操作指南!小规模纳税人请及时升级税控盘及税务UKEY开票软件升级操作指南!小规模纳税人请及时升级新增改进功能自2023年1月1日至2023年12月31日,增值税小规模纳税人适用3征收率的应税销售收入,减按1征收率基金最后一周怎么办昨天基金收益17781元,见下面的截图1,总资产中少了2W,挪借他人,几天就会回来的。昨天持有各只基金的收益情况,见下面的截图2和截图3,8红5绿,医疗是那个最红,银河是那个翠绿,张壮代表柳州市工业总量稳居广西各市首位来源人民网人民网南宁1月14日电(黄子婧吴明江)1月13日下午,广西十四届人大一次会议在广西人民会堂举行记者会。会上,据柳州市市长张壮代表介绍,2022年,柳州市工业总量稳居广西各科技长虹科技创新取得新突破,引领高质量发展来源四川日报川观新闻文伍佑图片由长虹控股集团提供厚积薄发的科技长虹迈入发展新征程。2022年长虹控股集团(以下简称长虹)的表现,可圈可点。2022年,在科技创新驱动与引领下,长虹各推途科技数字人怎么样,数字员工多少钱?推途科技数字人怎么样?随着人们对健康的关注度和需求度的逐渐上升,在健康中国的大背景下,也将有越来越多的医生以自身的专业知识做铺垫,在抖音平台上分享医学知识。同时,真人口播科普类短视数位股东已套现超60亿,千亿药妆巨头贝泰妮市值遭腰斩,还要继续跌?记者胡振明编辑1月13日(周五)收盘,贝泰妮(300957。SZ)股价为137。90元股(0。09),总市值584亿元。此前,1月12日收盘后,贝泰妮披露关于持股5以上股东减持股份千岛湖畔浪漫满屋来源淳安融媒体中心记者杨波千岛湖银泰城(新城店)项目位于经济开发区坪山核心区域,是集办公商业餐饮健身休闲于一体的商业综合体。其中新增的摩天轮项目,直径约61米,高约86米,是目前国