技术分享| anyRTC 服务单端口设计
传统的 CDN 比如 RTMP 直播,是基于 tcp 的服务,并不存在端口过多的情况;而 RTC 服务大多数用的是 udp 端口,这种 Udp 模式有很多的优点,但是相比于 RTMP 直播服务器单端口走天下,RTC 服务动则要开几百个端口略显尴尬。
RTC 绝大多数都是 udp 通讯,在进行互通的时候需要开放很多端口, 一个音/视频通道就要开启多个通道, 如果是多人音视频通话需要开通的端口更多. 对端口资源照成了很大的浪费, 一些防火墙会限制多 udp 端口的开放。如果要部署在服务端, 多端口的开发会给运维照成极大的不方便。
有的人会说,开放多个端口也没什么,实际场景中用着也没有出现问题。确实多端口本身没有问题,可以放心使用,我们只是在此基础上提出一种优化方案。
那么多端口到底有什么不足呢?
1)很多的网络出口防火墙对能够通过的 UDP 端口是有限制的。
2)对于服务端来说开辟这么多端口,安全性本身也有一定的问题,很容易被黑客扫描到进行攻击,特别是运维同学,更是拒绝。
3)开辟这么多的端口在 Server 端上,端口的开销和性能均有一定的影响。
4)行业特性要求,特别是金融、公安等对安全性要求特别高的行业,多端口是不可接受的。
如何减少 RTC 服务中端口的使用,甚至能否只使用 1 个端口呢?
目前为止已经有很多成熟的减少端口使用的策略:
1)Rtp/Rtcp 复用端口的方案 Rtcp-mux。
2)音视频的 Boundle, 可以让音视频复用连接通道。
3)多路流复用单连接的 plan b 和 unified plan 方案;PS:WebRTC 的 M89 版本正式废弃 plan b,所有 WebRTC 标准都已经转向了 unified plan。
这些策略都在不断的在消减端口的使用, 但即使上面的这些策略全部开启, 单个用户还是要占用最少一个端口, 如果一个 RTC 服务器要服务 500 个用户, 就要开启 500 个端口。
如何实现单端口,为我们需要了解一些技术点,这样实现起来思路就会更清晰:
1)SDP offer 和 answer 里配置的 ice-ufrag 字段里面内容,STUN Binding Request 里面的 USERNAME 字段就是由上 Offer 和 answer 的 ice-ufrag 内容拼接而成,这是用来作为 stun 数据包的鉴权的,因此可以作为一个标识为我们所用。
2)发送 STUN Binding Request 的客户端本地 udp socket,与 ice 建连成功后发送媒体数据的 udp socket 是同一个,那么对于服务端来说,客户端的 ip port 是同一个。
让我们来看看实现细节是怎么样的:
1)在服务端给客户端的 SDP Answer 中设置 ice-ufrag 为本服务上唯一的 ID,其中 ID 可以设计成业务层分配的内容,也可用于区分每对通话以及参与者。接着做 Ice candidate 协商,客户端开始做连通性检测,也就是 stun binding request 里的 USERNAME 为 SDP local 和 remote 的 ice-ufrag 指定内容。
2)服务端收到 stun binding request 的客户端 ip 和端口,并正常回 stun binding response。
3)服务端记录客户端地址与用户的信息的映射关系。
4)服务端收到一个 rtp/rtcp 媒体数据包,通过包的源 ip 和端口,查询映射表就可以识别这个包属于哪个连接的流。
这样就可以实现一个单端口模式的 RTC 服务,非常的简单。这里再给一个闭坑提示,在实际场景中,客户端的网络容易发生变化,比如手机的 wifi 切换成了 4/5G 网络,此时手机的外部出口 ip 端口已发生了变化,需要及时在服务端更新,否则会出现黑屏现象。
版权声明: 本文为 InfoQ 作者【anyRTC开发者】的原创文章。
原文链接:【http://xie.infoq.cn/article/db1e32941aa7db17966c9323b】。文章转载请联系作者。
评论