这是RFC 7016中所述的安全实时媒体流程协议(RTMFP)的C ++(11)实现。
该库包括示例平台适配器和其他实用程序,例如基于简单的select()的运行循环,但不需要使用这些循环。协议实施旨在适应任何主机程序环境。
该库适用于客户,服务器和P2P应用程序。它包括必要的助手和回调钩,以支持P2P简介和负载平衡。
test目录包括单位测试和示例。特别值得注意的是tcserver ,一个简单的RTMFP和RTMP Live Media Server; tcrelay ,RTMFP↔︎rtmp继电器/代理;和redirector ,一个简单的负载平衡器。
最完整的API文档当前在rtmfp.hpp标头文件中。
应用程序将实例化IPlatformAdapter和ICryptoAdapter ,然后是com::zenomt::rtmfp::RTMFP (需要这些适配器)。通常,需要告知平台适配器新的RTMFP实例,因此它可以调用实例的平台方法(例如howLongToSleep()和onReceivePacket() )。
该平台将通过调用RTMFP::addInterface()添加至少一个接口。
该应用程序可以使用RTMFP::openFlow()和Flow::openFlow打开向新的或当前端点发送流量,并且可以使用RecvFlow::openReturnFlow()打开关联的返回流。
该应用程序可以通过在RTMFP上设置onRecvFlow回调(用于裸机流)或SendFlow S(对于关联的返回流)上来接受新的流。
该应用程序可以通过SendFlow::write()将消息发送给遥远的同行,并通过在RecvFlow上设置onMessage回调”来接收来自遥远同行的消息。如果不是由每人截止日期开始或传递的消息,或使用SendFlow::write()返回的WriteReceipt s,消息可能会过期并被放弃。当消息传递或放弃时,可以通过回调通知该应用程序。
SendFlow s设置为优先/优先级PRI_PRIORITY , PRI_IMMEDIATE , PRI_FLASH或PRI_FLASHOVERRIDE被认为是时间至关重要。发送时间关键信息会影响拥塞控制。
完成后,应用程序可以有序或突然关闭RTMFP 。
协议实现是单线读取的,没有锁/静音。所有对其API的调用都必须在外部同步,例如,所有呼叫都在同一线程或类似于环形的构造中。这是为了提高便携性和性能,因为锁定在现代CPU上可能非常昂贵。平台适配器的perform方法抽象了同步,如果需要,可以将某些昂贵或耗时的操作卸载到其他内核/线程(如果需要)。
协议实现未直接与操作系统的UDP插座,时钟,运行循环,锁或线程进行交互。这些交互被抽象成主机程序提供的平台适配器。
平台适配器将是com::zenomt::rtmfp::IPlatformAdapter的具体实现,该实现称为“平台适配器使用”部分中的RTMFP公共实例方法。适配器提供了当前时间,读写和写作,以插入插座,时机和同步。
该库提供了两个示例平台适配器,这些适配器在RunLoop s: PosixPlatformAdapter中运行,用于纯单线程应用程序,以及PerformerPosixPlatformAdapter ,以允许将CPU密集型公共密钥密码学卸载到工作线程中。这些平台适配器应适用于类似Unix的操作系统上的许多应用程序,并应作为如何编写单读和多线程平台适配器的示例。
不需要平台适配器的接口是UDP插座。例如,接口可以是袜子或转动代理,隧道或网络模拟器。
对于类似于Unix的操作系统,该库提供了一个简单的基于select()的运行循环,适用于许多基于插座的应用程序。它还包括一个简单的基于epoll的Linux运行循环,该循环比select()来处理许多插座。使用PreferredRunLoop别名自动选择目标操作系统时的编译时可用的最佳变体。
可以将Performer连接到运行循环中,以启用内部调用任务/与任何线程的运行循环同步。 Performer S与PerformerPosixPlatformAdapter一起使用。
Microsoft Windows不是正式支持的平台。但是,核心库(不包括平台适配器,运行循环和Performer )应在Windows上构建,并且将尝试将该平台的核心维护作为时间和帮助。如果Windows上的核心库存在问题,请打开问题。
要在Windows上使用此库,您将需要提供适当的平台适配器。
请联系维护人员或打开问题,要求在此文档中添加到Windows平台适配器的链接。
RFC 7016描述了一个通用框架,该框架是根据应用程序的需求确保RTMFP通信的,并将加密详细信息留在加密概况中。该库不会将其应用程序锁定到任何特定的密码概要文件中,并编写以支持许多潜在的配置文件。加密概况由提供给RTMFP实例化的混凝土ICryptoAdapter实现。
RTMFP的大多数应用程序都将使用加密概况进行RFC 7425中描述的闪存通信。这是由FlashCryptoAdapter提供的。请注意,该适配器是抽象的,必须分类以提供所需的加密原始图的具体实现。 FlashCryptoAdapter_OpenSSL提供了使用OpenSL的具体实现,该实现也可以作为如何使用其他密码库的示例。如果您没有OpenSSL或不想使用它,则可以通过在WITHOUT_OPENSSL情况下make变量来抑制构建此模块。如果您的OPENSL安装在编译器的默认包含和链接搜索路径之外,则可以定义make变量OPENSSL_INCLUDEDIR和OPENSSL_LIBDIR并带有适当的指令(有关示例,请参见Makefile )。
FlashCryptoAdapter的OpenSSL实施4096位Internet密钥交换(IKE)组16、2048-BIT IKE组14和1024-BIT IKE组2 for Diffie-Hellman密钥协议。 Flash通信加密配置文件的所有实现都必须至少实施第2组;一些人还实施了第14组。此实施更喜欢最强大的共同组。
请注意,RTMFP不限于闪存平台通信。该库提供了适合测试和评估的PlainCryptoAdapter 。由于它不提供实际的加密术(及其cryptoHash256()和pseudoRandomBytes()方法特别弱),因此它不适合在开放互联网中生产使用。不。
BufferBloat(网络中的过度缓冲和排队)可能会导致高端到端延迟,从而导致实时应用程序的性能不可接受。不幸的是,目前尚未普遍部署此问题(带有明确拥塞通知的主动队列管理)的最佳解决方案。
除了正常的交通拥堵信号(损失和明确的拥塞通知)外,该图书馆还可以选择从往返时间增加(RTT)中推断出会议上的拥塞。要启用此功能,请使用Flow::setSessionCongestionDelay()设置高于基线RTT的额外延迟,以解释为交通拥堵的指示。默认值是INFINITY 。对于此功能,建议提出0.1秒的额外延迟值。
基线RTT是过去三分钟内最多观察到的最小RTT。在以下情况下清除基线RTT观测窗口并重置:
不时地使用拥塞窗口的很大一部分,将暂时减少拥塞窗口,以探测新的基线RTT的路径(如果我们自己的发送是掩盖了基线)。请注意,这可能会导致抖动。
如果观察到平滑的RTT高于基线以及配置的CongestionDelay (并且也至少为30ms),则假定这是拥塞的指示。拥塞控制者对此做出回应,好像是损失。
与所有基于端到端的延迟延迟一样,这种拥堵检测计划是不完善的,并且受到案件造成的假信号的约束:
因此,对于所有用例,可能不会指示此功能。只有在不太可能的误报充血信号(例如通过专用的瓶颈)实质上单向媒体传输时,才应注意才能启用此功能。误报会导致传播饥饿。
此功能的灵感来自较低的额外延迟背景传输(LEDBAT),多媒体(Scream)的自锁速率适应和Google的BBR拥塞控制算法。
RTMFP的实施增加了对明确的拥塞通知(ECN)的支持。它添加了一个新的实验块“ ECN报告”(类型为0xec ),以使接收器将接收到的ECN CodePoint的计数发送回ECN发件人。 RTMFP不得将ECN报告发送给其同行,除非它在其S_OPEN会话中至少收到了一个有效的数据包,该数据包与具有ECN具有ECN的运输代码点( ECT(0) , ECT(1)或ECN-CE )标记的同行。
具有ECN能力的RTMFP接收器将ECN报告发送给具有ECN的同伴。 ECN报告应在包含确认的任何数据包中的第一个确认块之前组装(以避免对报告的截断)。为了使ECN发件人能够检测到近距离接口,路径和接收器支持ECN,具有ECN能力的接收器应在任何包含确认的数据包中发送ECN报告,如果自从上次发送了ECN报告以来已收到的任何包含ECN能够运输代码点的数据包,或者尚未发送ECN报告。
如果RTMFP发件人确定接收器不可ECN的能力,则必须停止使用ECN能够运输代码点标记数据包(例如,如果发送者尚未收到至少一份ECN报告以及在与同伴开放期间在标记数据包中发送的用户数据的确认书)。
具有ECN能力的RTMFP接收器至少保留了带有ECN-CE数据包数量的计数。端点将当前计数器的低8位发送给其ECN报告中的同行。
此实现发送ECT(0) 。拥塞控制者对ECN-CE-count的增加做出了回应,好像是损失一样。 ECT(0)仅在包含用户数据的数据包上发送。
0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0xec | 1 | ECN-CE-count |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
struct ecnReportChunkPayload_t
{
uint8_t congestionExperiencedCountMod256; // ECN-CE-count
} :8;
congestionExperiencedCountMod256 :从带有ECN-CE (ECN拥塞经验丰富)的同伴收到的数据包的低8位。