随着网络基础设施的提高,音视频实时通信越来越成为人们日常生活和工作中必不可少的需求。2011年 WebRTC的出现,则更加速了这种需求变为现实的可能性。
熟悉 WebRTC 的同学应该都知道,WebRTC规范只定义了实时通信中客户端的行为,而没有规范服务端(包括哪些信令、数据如何流转)的行为。所以,你可以使用WebRTC库方便的实现 1:1 实时通信,但对于多人实时互动,光依靠 WebRTC库显然就无法完成要求了。
那我们该如何实现多人实时互动通信呢?
WebRTC 流媒体服务器
要想实现多人的实时互动,如音视频会议、在线教育这类产品,我们必须使用 WebRTC + WebRTC流媒体服务器这种方案。
目前有很多比较有名的开源流媒体服务器,如 Janus、Medooze、Mediasoup、Licode(OWT)、Jitsi等等。这些流媒体服务器各有优缺点,下面我就对这几种流媒体服务器作下简要的介绍与比较。
通过本文,你将知道各 WebRTC 流媒体服务器的优缺点,并依俱它们的优缺点选择出更适合你的那款WebRTC流媒体服务器。
Mediasoup
上图是Mediasoup整体架构图,通过该图我们可以知道 Mediasoup 流媒体服务器是由 Nodejs 和 Mediasoup(C++) 两部分组成。
- Nodejs,负责 Mediasoup 的信令接收与业务管理。如创建/消毁房间,创建/关闭生产者,创建/关闭消费者等。
- Mediasoup(C++),这是一个单独的程序,但该程序无法直接启动。因为它在内部会判断是否是 Nodejs 将它启动起来了。只有在Nodejs 的 Mediasoup 管理模块加载之后,再将 Mediasoup(C++)启动起来,这样它才能正常工作。
在众多的 WebRTC 流媒体服务器中,Mediasoup 可以说是性能最优秀的WebRTC流媒体服务器。它使用 C++ 作为开发语言,底层使用 libuv 处理 I/O 事件。
有很多人对 Nodejs 比较诟病,认为 Nodejs 提拱不了高性能的流媒体服务器。实际上,如果按照传输的 Nodejs 应用开发出的流媒体服务器肯定是不能胜任这项工作的。但对于 Mediasoup 来讲,它只不过使用 Nodejs 做 信令处理 及 业务的管理 工作,所以它的负担并不重。对性能要求高的是媒体数据流的转发工作,而这部分工作是由 Mediasoup(C++)部分实现的。Nodejs 与 Mediasoup之间通过管道进行通信。
严格意义上来说,Mediasoup是单进程的。但你不要以为这就影响了它的性能。实际上,它是使用单进程的方式将服务器上CPU某个 核
充分利用好,然后在业务层控制进程的个数。比如说你的服务器是个 8 核的CPU,那么在业务层你就该启动 8 个Mediasoup进程。通过这种方式来达到对 CPU 的充分利用。
Mediasoup中的每个进程称为一个 Worker, 你也可以把它理解为一个节点
,在每个 Worker 中可以有多个 Router。对于 Router,你站在不同的解度可以有不同的理解。如果你占在应用层的角度,你可以把它理解为一个房间;如果你站在数据流转的角度,可以把它理解为一个路由器,数据通过 路由器
转发给目标用户。
想了解更多Mediasoup的细节,可以观看我的视频课 《百万级高并发WebRTC流媒体服务器设计与开发》,在这个视频中我对 Mediasoup 源码做了深入剖析。
Janus
上面这张图是 Janus 的整体架构图。在这张图中我们可以看到, 从大的方面说 Janus 由 Janus CORE、Janus Plugin 以及信令接口三部分组成。
- 信令接口,Janus 支持的信令协议比较多,如 HTTP、WebSocket、RabbitMQ 等。这些信令协议使得 Janus 具有非常好的接入性。因为很多公司喜欢各种不同的协议,如有的喜欢 websocket,有的喜欢http,proto等。因此 Janus 在信令接入方面具有很大的优势。
- Janus Plugin,Janus 的业务管理是按照 Plugin 的方式管理的,因此你可以在Janus中根据自己的需要实现自己的业务插件。实际上,对于一般性的需求 Janus 已经相关的插件。如:
- VideoRoom,用于多人音视频互动,像音视频会议,在线教育都可以通过该插件来实现。
- VideoCall,用于 1:1 的音视频通信。
- SIP,用于与传统电话设备对接。
- Streaming,用于广播,也就是我们通常所说的一人共享,多人观看的直播模式。
- TextRoom,它是一个聊天室,通过它可以进行文本聊天。
- RecordPlay,用于录制和回放。
- Janus Core 是Janus的核心,其作用是处理流的转发,各种协议的接入。以浏览器为例,要想让浏览器接入到 WebRTC 流媒体服务器上,那流媒体服务器必须要支持 STUN、DTLS、SRTP、ICE 等协议。而 Janus Core 就是专门做这事儿的。
Janus 是由 C语言开发的,因此它的性能非常优秀。要说不足的话,janus 底层没有使用 epoll 这类异步I/O事件处理机制,这应该说是它的一大缺陷;另外,Janus还使用 glib 库,由于 glib 库对于国内的很多开发同学来说用的比较少,所以会有一定的学习成本。
整体上看,Janus采用了插件的架构设计方案。这种方案非常适合于有多种业务模型或业务经常发生变化的公司或项目。另外 Janus 支持多种消息传输协议,这对于开发人员来说具有极大的吸引力。
Medooze
Medooze 的整体架构与 Mediasoup 类似,不过它的信令处理、业务管理以及媒体数据的转发功能都是放在 Nodejs下进行统一管理的。实际上,这样的管理方式也不会对性能造成什么影响,因为重的媒体流的转发工作仍然是使用的 C++ 在 Nodejs 底层实现的。
Medooze 的业务功能要比 Mediasoup 强大,像服务端录制、推流这些 Mediasoup 没有的功能它都支持。但它性能没有 Mediasoup 做的极致,在Medooze的底层使用的poll来处理I/O事件,poll与epoll性能相差距大。除此之外,Medooze的业务逻辑也没有Mediasoup简洁;另外与 Janus 相比,它的业务管理不如 Janus 灵活,Janus 的插件管理方式显然要优于 Medooze 和 mediasoup。
但总的来说,Medooze还是一款非常不错的 WebRTC 流媒体服务器。虽然有一些小的暇疵,但还是非常不错的一款流媒体服务器。
想了解更多 Medooze 细节的同学可以看我的专栏 《从0打造音视频直播系统》。
小结
通过上面的描述,我想你应该对目前主流的 WebRTC 流媒体服务器有了一个大体的了解。所以在选型上你可以按照自己团队的能力进行评估到底该用那个流媒体服务器。
如果你团队能力比较强,可以做底层开发,那么建议你使用 Mediasoup。因为 Mediasoup 不关心应用层,它关注的是底层数据如何高效的流转,代码简洁、高效,性能极佳。
如果你们要做的业务种类比较多,变化比较快,那建议你选择使用 Janus 作为流媒体服务器。将你的业务做成一个插件放到 Janus上很快就能实现你们的业务需求。
如果你们的业务变化不大,除了追求性能外,还需要录制、推流之类的功能,那么你可以选择使用Medooze,它可以很好的满足你们的需求。
当然,除了上面我介绍到的几款比较流行的 WebRTC 流媒体服务器外,还有一些其它的流媒体服务器,如 Licode、OWT、Jitsi等也可以选择。
Licode 之所以名气比较大,是因为它推出的时间比较早。而 OWT 是 Licode 的一个变种,它在 Licode上实现了 SFU 功能。看一下 Licode 代码你就会发现,Licode 实现了一套完整的音视频会议系统,对于这样一套系统它的实现非常复杂。如果你的团队没有音视频方面的开发人才的话,可以考虑Licode,将它搭建出来之后就可以直接使用了。但如果你有业务变化想修改它就太麻烦了。
Jitsi 上层是使用 Java 语言开发的,但底层也是使用的 C/C++ 语言。它通过 JNI 来实现Java与 C/C++之间的通信。在 2018 年有机构做过一次性能评测,当时 Jitsi 表现比较差强人意,不知现在是否已经有了改进。
以上就是对几款 WebRTC流媒体服务器的比较,希望本文可以帮助你解决WebRTC流媒体服务器的选择问题。