mediasoup Transport端口策略

 一. 前言

        mediasoup 支持多种类型的 Transport,有 WebRtcTransport,PlainTransport 以及 PipeTransport,对于 WebRtcTransport 目前 mediasoup 最新版本已经支持多个 WebRtcTransport 共用单个端口的模式了,而在此之前每个 WebRtcTransport 都需要使用一个端口,对于 PlainTransport 和 PipeTransport 现在还是每个通道需要对应一个端口。

二. WebRtcTransport单端口设计

        mediasoup-demo-server 的启动配置文件中有 webRtcServerOptions 的配置选项,每个 worker 创建后 nodejs 层会通过 worker.createWebRtcServer 创建一个 WebRtcServer 的实例对象,WebRtcServer 具有 WebRtcTransport 的能力,如下所示。

        对于上述配置,如果启动了多个 mediasoup-worker,不同 worker 监听的是不同的端口,第一个 worker 监听 44444,第二个 worker 监听 44445,以此类推。

        当 mediasoup-client 调用 createWebRtcTransport 信令请求创建一个 WebRtc 通道时,nodejs 会通过 router.createWebRtcTransportWithServer 方法请求 mediasoup-worker,mediasoup-worker 创建 WebRtcTransport 是先通过 WebRtcServer 进行处理的,candidate 中填充的 port 信息都是 WebRtcServer 监听的 port,所以同一个 mediasoup-worker 上的所有 WebRtcTransport 使用的端口都是相同的。

        返回 WebRtcTransport 的 ice candidate 信息后,SDK 会发送 STUN / RTP / RTCP 等不同类型的报文,那么 mediasoup 从固定端口收到报文之后是怎么分发给到具体的 Transport 进行处理呢?

        答案是通过四元组信息,即便 server 监听的是固定端口,但是对端的 (ip, port) 是不相同的,当 mediasoup server 收到报文之后查找是哪个对端 (ip, port) 发送过来的包,再找到对应的 transport,将数据塞给对应的 transport 处理,涉及的调用流程如下。

        WebRtcServer 启动监听时会创建 UdpSocket,此时 UdpSocket 的 listener 指向 WebRtcServer 对象,当有数据包到达时会回调 UdpSocket::UserOnUdpDatagramReceived,再继续回调到 WebRtcServer::OnUdpSocketPacketReceived。

        对于 OnStunDataReceived 和 OnNonStunDataReceived,它们内部都是先首先根据对端地址查找到对应的 WebRtcTransport,然后交给对应的 WebRtcTransport 进行处理,例如 STUN 类型的报文就调用 webRtcTransport->ProcessStunPacketFromWebRtcServer(tuple, packet) 处理,非 STUN 类型的报文就调用 webRtcTransport->ProcessNonStunPacketFromWebRtcServer(tuple, data, len) 处理。

三. PlainTransport/PipeTransport多端口设计

        PlainTransport 和 PipeTransport 一个通道使用一个端口,新建 Transport 时会创建 UdpSocket 对象,UdpSocket 需要关联到 (ip, port),对于端口的选取是通过 PortManager::BindUdp 函数实现的,如下。

        端口选取的逻辑如下,它从配置的 [rtcMinPort, rtcMaxPort] 中随机选择,如果端口已经被标记使用则更换下一个端口,如果未被标记使用则通过 uv_udp_bind 关联此端口后,如果成功再标记端口被使用,如果失败则更换下一个端口(失败是有可能已经被其他 worker 占用了,该端口有已打开的句柄),之后在 UdpSocket 的析构函数会执行 PortManager::UnbindUdp 函数重新解除使用标记。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

椛茶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值