正文字数:2848 阅读时长:4分钟
在研究如何使视频通话在未来更高效,更易于扩展时,Facebook意识到,最好的方法是从头开始重新设计库并重写整个库,也就是Rsys。
作者 / Ishan Khot
我们将在我们的应用程序和服务的所有相关产品上推出一个新的视频通话库,包括Instagram、Messenger、Portal、Workplace chat等。
通过创建一个通用类库足以支持所有这些不同的用例,但我们需要从头重写现有库使用最新版本的开源的WebRTC库。这是一个非常令人难以置信的任务,以至于我们整个公司的工程师都参与到了其中。
与前面的库相比,Rsys能够支持多个平台,包括Android, iOS, MacOS, Windows和Linux。它的大小大约小了20%,这使得它很容易集成到大小受限的平台中,比如Messenger Lite。Rsys拥有大约90%的单元测试覆盖率和一个完整的集成测试框架,它涵盖了我们所有的主要调用场景。
为此,我们通过将库和体系结构的大小优化为二进制大小来实现这一目标,方法是将调用所需的部分分成独立的独立模块,并利用不依赖于操作系统和环境的跨平台解决方案。
Facebook的视频通话初始版本是在一个已有7年历史的WebRTC分支上编写的,专门用于在Messenger中启用本机音频通话。当时,我们的目标是为我们的用户提供功能最丰富的体验。从那时起,我们添加了视频通话,群组通话,视频聊天引擎和交互式AR效果。每月有数百万人使用视频通话,这个功能齐全的库表面上看起来简单,但在幕后却变得复杂得多。我们有大量特定于Messenger的代码,这使得我们很难支持像Portal和Instagram这样的应用程序。对于组调用和对等调用,我们有单独的信令协议,这要求我们编写两次特征,并在代码库中造成很大的不一致。我们还花费了更多的时间来更新WebRTC的分支,并使用开源的最新改进功能。但最后,我们发现我们在为低功耗设备和低带宽场景提供可靠服务方面落后了。
在研究如何使视频通话在未来更高效,更易于扩展时,我们意识到,最好的方法是从头开始重新设计库并重写整个库。结果就是Rsys,这是一个视频通话库,它让我们能够利用自2014年编写原始库以来在视频通话领域取得的一些重大进步。与以前的版本相比,Rsys缩小了约20%,并且可在所有开发中使用平台。通过这一新的迭代,我们将重新构想我们对视频通话平台的看法,并从头开始使用新的客户端核心和可扩展性框架。这有助于我们提升自己的最先进技术,新的代码库旨在在未来十年保持可持续性和可扩展性,为跨应用程序的远程存在和互操作性奠定基础。
更快更小
无论设备类型或网络条件如何,使用较小的代码库可以为其用户实现更快地加载、更新和启动。相比之下,小型库也更易于管理、更新、测试和优化。当我们开始考虑准备新的版本时,我们的峰值二进制大小已高达20 MB。尽管我们可以通过编辑一些代码段来减少一些内容,但是要达到我们想要的效果,我们意识到我们需要从头开始重写整个代码库。
想要获得较小的库,最简单方法是去掉多年来我们添加的许多功能特征,但是对我们来说,保留所有最常用的功能(如AR效果)很重要。因此,我们退后一步,研究了如何应用过去十年中所学到的知识以及我们对如今使用我们产品的用户的需求了解。探索完我们的这些选择之后,我们决定需要越过接口,并深入研究库本身的基础结构。
我们做了几个架构选择来优化大小,引入了一个即插即用的框架,使用selects有选择地将特征编译到需要它们的应用程序中,并引入了一个通用框架来编写基于Flux架构的新特性。我们也从Folly这样的模板化通用库转向了像Boost这样规模更优的库。SML在所有应用程序中实现大小增益。
最后,我们将核心二进制文件的大小减少了大约20%,从大约9MB减少到大约7MB。我们通过重新构建我们的特征以适应简化的体系结构和设计来实现这一点。虽然我们保留了大部分特性,但随着时间的推移,我们将继续引入更多可插入特性。更少的代码行数使代码库更轻、更快、更可靠,而精简的代码库意味着工程师可以更快地进行创新。
这项工作的主要目标之一是最小化代码复杂性和消除冗余。我们知道,一个统一的体系结构将允许全局优化(而不是让每个特性都集中在局部优化上),并允许代码重用。为了构建这个统一的体系结构,我们做了一些主要的更改:
信令:我们为信令栈提出了一种状态机架构,它可以统一对等调用和组调用协议语义。我们能够从库的其余部分抽象出任何特定于协议的细节,并提供一个信令组件,该组件将全权负责在调用参与者之间协商共享状态。通过减少重复代码,我们可以一次编写特性,并允许轻松更改协议,并为对等调用和组调用提供统一的用户体验。
媒体:我们决定重用我们的状态机架构,并将其应用到媒体堆栈中,但这次我们捕获了开源WebRTCAPI的语义。同时,我们还致力于用最新版本替换我们的分支版本WebRTC,同时保留所有针对产品的特定优化。这使我们能够在状态机下更改WebRTC版本,只要API本身的语义没有明显变化,我们就可以从开放源码代码库中设置定期常规拉取。这使我们能够轻松地更新到最新的功能,而不会出现任何停机或延迟。
SDK:为了具有特定于功能的状态,我们使用Flux架构来管理数据,并为调用产品提供API,这些API的工作原理类似于web开发人员熟悉的基于React js的应用程序。每个API调用都会导致通过中央调度程序路由的特定操作。然后,这些动作由特定的reducer类处理,并根据动作的类型发出模型对象。这些模型对象被发送到包含所有特定于功能的业务逻辑的网桥,并导致更改模型的后续操作。最后,所有的模型更新都被发送到UI,在那里它们被转换成特定于平台的视图对象进行渲染。这使我们能够清晰地定义一个包含减速器、桥接器、动作和模型的特性,从而使我们能够在运行时为不同的应用程序配置特性。
OS:为了使我们的平台具有通用性和可扩展性,我们决定抽象出直接依赖于OS的所有功能。我们知道,对于某些功能(例如创建硬件编码器,解码器,线程抽象等),必须具有针对Android,iOS等的特定于平台的代码,但是我们尝试为这些功能创建通用接口,以便MacOS和Windows等平台可以通过代理对象提供不同的实现来轻松插入。我们还大量使用Buck中的cxx_library来以简便的方式配置特定于平台的库,以用于编译器标志,链接器参数等。
用于调用的Rsys架构
下一步的计划
如今,我们的调用平台明显要小得多,并且能够在许多不同的用例和平台上扩展。我们支持每天都有数百万人使用的电话。我们的库是我们所有主要通话应用程序的一部分,包括Messenger,Instagram,Portal和Workplacechat。构建Rsys需要一个很长的过程,但是,对于使用这些应用程序的人们来说,它的感觉并没有太大不同。它将继续为人们提供出色的通话体验。但这仅仅是开始。
我们在Rsys中所做的工作将使我们在迈向未来的过程中能够继续创新和扩展我们的通话体验。除了构建可在未来十年或更长时间保持可持续发展的库之外,这项工作还为我们所有应用的跨应用调用奠定了基础。它也为我们建立以远程存在为中心的环境奠定了基础。
这项工作得益于与客户平台团队合作。我们感谢所有为Rsys做出贡献的人,特别是Ed Munoz,Hani Atassi,Alice Meng,Shelly Willard,Val Kozina,Adam Hill,Matt Hammerly,Ondrej Lehecka,Eugene Agafonov,Michael Stella,Cameron Pickett,Ian Petersen和Mudit Goel在实施方面提供了帮助,并继续提供指导和支持。
LiveVideoStackCon 2021 ShangHai
这个世界没有准备好这一说
机会和技术不会主动敲开你的门
LiveVideoStackCon 2021 上海站
北京时间:2021年4月16日-4月17日
领取专属 10元无门槛券
私享最新 技术干货