当前位置: 首页 > news >正文

做网站湖州中国制造网外贸平台

做网站湖州,中国制造网外贸平台,网站开发深圳,淄博学校网站建设公司mediasoup 提供了多种 transport#xff0c;包括 WebRtcTransport、PipeTransport、DirectTransport、PlainTransport 等#xff0c;用来实现不同目的和场景的媒体通信。WebRtcTransport 是 mediasoup 实现与 WebRTC 客户端进行媒体通信的对象#xff0c;是 mediasoup 最重要…mediasoup 提供了多种 transport包括 WebRtcTransport、PipeTransport、DirectTransport、PlainTransport 等用来实现不同目的和场景的媒体通信。WebRtcTransport 是 mediasoup 实现与 WebRTC 客户端进行媒体通信的对象是 mediasoup 最重要也是最复杂的 transport理解了 WebRtcTransport 的设计与实现再去分析其他类型 transport 会简单很多。 1. 静态结构 WebRtcTransport 可以创建独立通信端口也可以共享 WebRtcServer 上的通信端口从安全和运维复杂度来讲大部分场景都应该选择第二种方式本文主要分析第二种实现方式。 1.1. WebRtcTransport 1.1.1. 接口继承 1Transport 这是所有 transport 的基类代表与具体协议无关的通信端口它封装了通信端口参与上层数据交换的公共能力比如如何与 router、producer、consumer 的关联与交互等。 2UdpSocket::Listener WebRtcTransport 建立独立通信端口时接收 UDP 数据。 class Listener { public:virtual void OnUdpSocketPacketReceived(RTC::UdpSocket* socket, const uint8_t* data, size_t len, const struct sockaddr* remoteAddr) 0; }; 3TcpServer::Listener WebRtcTransport 建立独立通信端口时处理 TCP 连接关闭。 class Listener { public:virtual void OnRtcTcpConnectionClosed(RTC::TcpServer* tcpServer, RTC::TcpConnection* connection) 0; }; 4TcpConnection::Listener WebRtcTransport 建立独立通信端口时接收 TCP 数据。 class Listener { public:virtual void OnTcpConnectionPacketReceived(RTC::TcpConnection* connection, const uint8_t* data, size_t len) 0; }; 5IceServer::Listener ICE 交互相关回调具体见注释。 class Listener { public:// 通知发送 stun 报文virtual void OnIceServerSendStunPacket(const RTC::IceServer* iceServer, const RTC::StunPacket* packet, RTC::TransportTuple* tuple) 0;// 通知添加/删除 ufrag主要用于 WebRtcServer stun 报文路由virtual void OnIceServerLocalUsernameFragmentAdded(const RTC::IceServer* iceServer, const std::string usernameFragment) 0;virtual void OnIceServerLocalUsernameFragmentRemoved(const RTC::IceServer* iceServer, const std::string usernameFragment) 0;// 通知添加/删除 tuple用于 WebRtcServer 非 stun 报文路由virtual void OnIceServerTupleAdded(const RTC::IceServer* iceServer, RTC::TransportTuple* tuple) 0;virtual void OnIceServerTupleRemoved(const RTC::IceServer* iceServer, RTC::TransportTuple* tuple) 0;virtual void OnIceServerSelectedTuple(const RTC::IceServer* iceServer, RTC::TransportTuple* tuple) 0;// WebRTC 客户端与服务器通信端口连接状态变化通知virtual void OnIceServerConnected(const RTC::IceServer* iceServer) 0;virtual void OnIceServerCompleted(const RTC::IceServer* iceServer) 0;virtual void OnIceServerDisconnected(const RTC::IceServer* iceServer) 0; }; 6DtlsTransport::Listener DTLS 相关回调详见注释。 class Listener { public:// 接收方向协商成功virtual void OnDtlsTransportConnecting(const RTC::DtlsTransport* dtlsTransport) 0;// 双向协商成功virtual void OnDtlsTransportConnected(const RTC::DtlsTransport* dtlsTransport,RTC::SrtpSession::CryptoSuite srtpCryptoSuite,uint8_t* srtpLocalKey,size_t srtpLocalKeyLen,uint8_t* srtpRemoteKey,size_t srtpRemoteKeyLen,std::string remoteCert) 0;// 连接失败或异常中断virtual void OnDtlsTransportFailed(const RTC::DtlsTransport* dtlsTransport) 0;// 对方关闭 DTLS 连接close_notify alertvirtual void OnDtlsTransportClosed(const RTC::DtlsTransport* dtlsTransport) 0;// 向对端发送 DTLS 数据DTLS协议交互virtual void OnDtlsTransportSendData(const RTC::DtlsTransport* dtlsTransport, const uint8_t* data, size_t len) 0;// 收到 DTLS 应用层数据virtual void OnDtlsTransportApplicationDataReceived(const RTC::DtlsTransport* dtlsTransport, const uint8_t* data, size_t len) 0; }; 1.1.2. 重要属性 1webRtcTransportListener 主要用于 WebRtcTransport 通知 WebRtcServer 相关信息用来建立数据路由。 class WebRtcTransportListener { public:virtual void OnWebRtcTransportCreated(RTC::WebRtcTransport* webRtcTransport) 0;virtual void OnWebRtcTransportClosed(RTC::WebRtcTransport* webRtcTransport) 0;// ICE 协议交互阶段需要使用 ufrag 来建立路由virtual void OnWebRtcTransportLocalIceUsernameFragmentAdded(RTC::WebRtcTransport* webRtcTransport, const std::string usernameFragment) 0;virtual void OnWebRtcTransportLocalIceUsernameFragmentRemoved(RTC::WebRtcTransport* webRtcTransport, const std::string usernameFragment) 0;// ICE 协议交互完成后需要使用 TransportTuple 来建立路由virtual void OnWebRtcTransportTransportTupleAdded(RTC::WebRtcTransport* webRtcTransport, RTC::TransportTuple* tuple) 0;virtual void OnWebRtcTransportTransportTupleRemoved(RTC::WebRtcTransport* webRtcTransport, RTC::TransportTuple* tuple) 0; }; 2iceServer 处理 ICE 协议交互确定用于通信的 TransportTuple。 3udpSockets WebRtcTransport 建立独立通信端口的 UDP socket。 4tcpServers WebRtcTransport 建立独立通信端口的 TCP 监听器。 5dtlsTransport 处理 DTLS 协商协商得到 SRTP 所需的加解密参数。 6srtpRecvSession 用于接收方向的 SRTP 解密。 7srtpSendSession 用于发送方向的 SRTP 加密。 1.2. IceServer 1.2.1. 重要属性 1usernameFragment 和 password 本端生成的随机值对应 SDP 中的 ice-ufrag 和 ice-pwd 2oldUsernameFragment 和 oldPassword 用来协助处理 ICE 重协商。 2consentTimeoutMs 客户端需要定时发送 Bind 请求进行保活这是相关超时设置。 4state ICE 协商状态具体见下面的状态机分析。 enum class IceState {NEW 1,CONNECTED,COMPLETED,DISCONNECTED, }; 5remoteNomination 正常情况是使用 USE-CANDIDATE 属性来选择用来通信的 candidate当没有 USE-CANDIDATE 属性时但携带了 NOMINATION 属性则可以使用 nomination 来选择通信 candidate值越大地址优先级越高。 6tuples 保存接收到客户端所有 BIND 请求的地址。 7selectedTuple 最终选择使用的通信地址对。 1.2.2. 重要方法 1ProcessStunPacket WebRtcTransport 调用用来处理 BIND 请求。 2RestartIce 当客户端发起 ICE 重协商时调用此接口此时会重新生成 ufrag 和 pwd。 1.3. DtlsTransport DtlsTransport 用来处理 DTLS 协议交互完成身份验证和密钥协商。一旦 DTLS 完成握手并协商好密钥后续RTP报文就不再通过 DTLS 处理而是通过 SRTP 进行加密和解密。 1.3.1. 重要属性 1listener 用来通知 DTLS 连接状态DTLS 协议报文需要经过 WebRtcTransport 发送另外 SCTP报文会被封装在DTLS报文中进行传输通过 OnDtlsTransportApplicationDataReceived 回调收到的 SCTP 数据。 2ssl 处于 SSL 协议交互的 OpenSSL 对象。 3state DTLS 连接状态具体见 DTLS 状态机分析。 enum class DtlsState {NEW 1,CONNECTING,CONNECTED,FAILED,CLOSED }; 4localRole DTLS 角色主要用于确定DTLS握手过程中的通信方向和权限通常是 CLIENT 发起握手。 enum class Role {AUTO 1,CLIENT,SERVER }; mediasoup 根据客户端 DTLS 角色来设置本端 DTLS 角色调用 connectWebRtcTransport 传递并返回协商结果给客户端。 // Set local DTLS role. switch (dtlsRemoteRole) {case RTC::DtlsTransport::Role::CLIENT:{this-dtlsRole RTC::DtlsTransport::Role::SERVER;break;}// If the peer has role auto we become client since we are ICE controlled.case RTC::DtlsTransport::Role::SERVER:case RTC::DtlsTransport::Role::AUTO:{this-dtlsRole RTC::DtlsTransport::Role::CLIENT;break;} } 5remoteFingerprint 保存客户端的证书指纹用来验证 DTLS 协商时对端证书的合法性。 6remoteCert 保存客户端的证书。 1.3.2. 重要方法 1ProcessDtlsData WebRtcTransport 调用此接口传入 DTLS 报文。 2SetRemoteFingerprint 在建立 DTLS 连接之前服务器需要调用此接口设置客户端的证书指纹否则无法对客户端证书进行验证。 3SendDtlsData OpenSSL 回调需要发送协商报文内部会调用回调 WebRtcTransport 进行发送。 4SendApplicationData 发送 SCTP 数据。 2. 数据流 WebRtcTransport 在进行媒体通信前要经历两个阶段第一个阶段是 ICE 协议交互用来确定进行通信的地址对第二个阶段是 DTLS 协议交互用来实现身份认证和密钥协商。这两个阶段完成后才开始进行 RTP/RTCP 传输阶段并使用 DTLS 阶段协商的密钥对淑军进行加解密。 2.1. STUN WebRtcServer 收到 UDP 数据时会解析报文特征识别报文类型然后调用 ProcessStunPacketFromWebRtcServer 处理 STUN 报文WebRtcTransport 将 STUN 报文丢给 IceServer 处理。IceServer 处理完后如果需要发送响应的则会回调 WebRtcTransportWebRtcTransport 调用 TransportTuple 将报文发送出去。 但这里有个问题WebRtcServer 如何知道 STUN 报文属于哪个 WebRtcTransport方法是WebRtcTransport 在创建 IceServer时会将 ice-ufrag 与 WebRtcTransport 关联起来。WebRtcServer 通过解析 STUN 报文的 ufrag 字段找到所属 WebRtcTransport。 同时WebRtcTransport 还会将 ICE 交互过程中所有地址对设置到 WebRtcServer这样后续从这些地址发送过来的报文都送到关联的 WebRtcTransport 处理不用再依赖 ufrag 字段。当然非 STUN 报文也没有这个字段可用。 2.2. DTLS DTLS 的数据流与 STUN 数据流类似只是在 WebRtcTransport 会对非 STUN 数据进行解析如果是 DTLS 协议报文会调用 DtlsTransport::ProcessDtlsData 进行处理。如果需要发送 DTLS 协议报文也是回调 WebRtcTransport 发送。 2.3. RTP RTP 数据流相对复杂一些涉及到转发层的路由如下图所示。 1WebRtcTransport 将收到的 RTP 报文交给 Transport 处理。 2Transport 通过报文的 SSRC 找到对应的 Producer然后将报文交给 Producer 处理。 【注】在 Worker 上创建 Producer 时需要传入 RtpParameters里面包含了 SSRC、MID、RID 等信息。Worker 会将这些信息与 Producer 关联起来当收到报文时可以基于这些信息找到对应的 Producer。 3Producer 需要做拥塞控制、NACK、关键帧请求等相关处理。处理完后会回调 Transport 进行后续的报文转发。 4Transport 直接将报文转发给 Router 处理。 【注】Transport 是在 Router 上创建的Transport 只能属于某个 Router。 5Router 将报文转发给所有连接到 Producer 的 Consumer。 6Consumer 也需要做拥塞控制NACK、关键帧请求等相关处理。处理完后会回调 Consumer 所在 Transport将报文发送出去。 3. 补充分析 3.1. 证书指纹 证书指纹fingerprint用来验证对等端的合法性有效防止中间人攻击。证书中不携带证书指纹需要通过其他方式来传递和交换。WebRTC 在 SDP 中携带证书指纹如下所示。fingergpinrt 分为两段第一段为摘要算法类型第二段为使用此摘要算法计算的证书摘要值。 afingerprint:sha-512 28:8D:69:62:88:27:68:0B:41:FB:BE:28:DE:63:F0:2D:7C:AA:38:72:57:58:37:D4:BD:B9:BE:01:9D:A1:AF:86:1D:BB:9F:36:76:04:A8:0D:24:80:5C:08:D7:70:0D:BA:54:06:CC:48:27:52:DE:00:CD:72:B3:1A:E6:15:F1:7D mediasoup 的证书指纹通过 connectWebRtcTransport 流程传递到 Worker如下图所示 证书指纹的计算方式可以简单的描述为基于 X509 规范对证书内容使用指定的哈希算法计算摘要。 ret X509_digest(certificate, hashFunction, binaryFingerprint, size); 在 DTLS 握手过程中Worker 会验证对等端的证书与设置的指纹是否匹配 如果匹配则验证通过握手继续进行如果不匹配则握手失败连接终止。 3.2. 密钥协商 mediasoup 预置支持的加密套件如下所示 std::vectorDtlsTransport::SrtpCryptoSuiteMapEntry DtlsTransport::srtpCryptoSuites {{ RTC::SrtpSession::CryptoSuite::AEAD_AES_256_GCM, SRTP_AEAD_AES_256_GCM },{ RTC::SrtpSession::CryptoSuite::AEAD_AES_128_GCM, SRTP_AEAD_AES_128_GCM },{ RTC::SrtpSession::CryptoSuite::AES_CM_128_HMAC_SHA1_80, SRTP_AES128_CM_SHA1_80 },{ RTC::SrtpSession::CryptoSuite::AES_CM_128_HMAC_SHA1_32, SRTP_AES128_CM_SHA1_32 } }; 通过下面代码设置将支持的 SRTP 的加密套件设置到 SSL。 // 设置SRTP加密套件 ret SSL_CTX_set_tlsext_use_srtp(DtlsTransport::sslCtx, dtlsSrtpCryptoSuites.c_str()); 最终协商结果是两套密钥盐客户端和服务器使用独立的密钥进行加密。 // Create the SRTP local master key. std::memcpy(srtpLocalMasterKey, srtpLocalKey, srtpKeyLength); std::memcpy(srtpLocalMasterKey srtpKeyLength, srtpLocalSalt, srtpSaltLength);// Create the SRTP remote master key. std::memcpy(srtpRemoteMasterKey, srtpRemoteKey, srtpKeyLength); std::memcpy(srtpRemoteMasterKey srtpKeyLength, srtpRemoteSalt, srtpSaltLength); 3.3. 重启 ICE 如果网络条件发生变化例如网络断开或切换则可能需要重新启动ICE进程以便重新发现和建立有效的网络连接。如下图所示如果在 DEMO 上点击所示图标会触发 ICE 重启。 客户端先调用服务器接口获取服务器更新后的 ICE 参数使用新的 ICE 参数更新 remote SDP再进行 PeerConnection 的 SDP 重协商。 async restartIce(iceParameters: IceParameters): Promisevoid {this.assertNotClosed();// 更新 ICE 参数ufrag/pwdthis._remoteSdp!.updateIceParameters(iceParameters);if (!this._transportReady) {return;}// SDP 重协商if (this._direction send) {const offer await this._pc.createOffer({ iceRestart: true });await this._pc.setLocalDescription(offer);const answer { type: answer, sdp: this._remoteSdp!.getSdp() };await this._pc.setRemoteDescription(answer);} else {const offer { type: offer, sdp: this._remoteSdp!.getSdp() };await this._pc.setRemoteDescription(offer);const answer await this._pc.createAnswer();await this._pc.setLocalDescription(answer);} } 3.4. ICE 状态机 USE_CANDIDATE 属性用于指示特定的候选对candidate pair被选为用于传输。mediasoup 收到 Binding 请求如果携带 USE_CANDIDATE 属性则进入 COMPLETED 状态否则进入 CONNECTED 状态。客户端要定时向服务器发送 binding 请求来保活如果超时则进入 DISCONNECTED 状态。 3.5. DTLS 状态机 DTLS 状态比较简单在 CONNECTING 状态如果证书验证失败、加密套件协商失败或者协商超时都会进入 FAILED 状态。在 CONNECTED 状态如果收到关闭请求则进入到 CLOSED 状态。DTLS 连接成功后好像没有保活处理看起来像是依赖于 ICE 的保活。 4. 总结 本文重点分析了 WebRtcTransport 的静态结构及重要数据流对于理解 mediasoup 媒体转发框架非常重要。建立 WebRtcTransport 需要经历 ICE 协商和 DTLS 协商两个阶段本文只对其中几个比较重要的逻辑进行了分析不涉及 ICE 协商和 DTLS 协商的协议细节如有需要请参考其他文档。
http://www.ho-use.cn/article/10821848.html

相关文章:

  • 专门做超市海报的网站做网站app是什么h行业
  • 做网站后台维护的岗位叫什么阿里指数查询官网入口
  • 网站建设公司做网站要多少费用国内外创意网站欣赏
  • 上海自适应网站制作建立网站需要哪些费用
  • 做号网站吗宁波网站建设公司哪家好
  • 网站建设中的图片网站设计高端网站制作
  • 怎么用阿里云建网站南京营销型网站制作
  • 如何制作一个公司网站网站设计 素材
  • 重庆手机网站推广2020最近的新闻大事10条
  • 小公司网站建设费用网页网站公司如何做备份
  • 网站建设与运营在线考试营销型网站整体优化
  • 建设网站需要什么技术支持卖辅助网站怎么做
  • 中国建设银行网站首页下载建设安全备案登入那个网站
  • 网赌网站怎么做的1 建设网站目的是什么意思
  • 抄袭网站后台会侵权吗网络科技公司取什么名字好
  • 成都营销网站设计赣州营销公司
  • 传动设备 技术支持 东莞网站建设微信电子宣传册制作app
  • 河北燕郊网站制作logo素材网站有哪些
  • 惠州免费建站模板自助网站建设怎么建设
  • 温州seo网站建设国家工商信息公示系统
  • 做网站公司做网站公司网络优化工程师前景
  • 网站推广方案中确定目标是指小吃培训机构排名前十
  • 网站模块是什么基于cms系统网站的建设
  • 玄圭做网站怎么样厦门 网站建设 闽icp
  • 建立自己网站的好处惠城网站建设费用
  • 昆山市有没有做网站设计的wordpress熊掌号文章提交
  • 黑河建设网站网站建设公司 石景山
  • 怎么在境外做网站扬州网站开发公司
  • 网站项目运营dw做的网站怎么在vs
  • 长沙影楼网站建设网络推广服务合同范本大全免费版