什么是心跳机制
心跳是为了确保前端后端,相互知道对方是否还存活着,定期发送一定的数据到对方那边。一般心跳的频率不会太高,太高会影响服务器性能。但是也不能太低,太低了,中间间隔太久中间变数太多。一般我们设置5~10s左右。
心跳机制主要用于保持与对等体的连接活跃,检测连接状态,以及在必要时重新建立连接。以下是心跳机制的一些关键点:
1. 心跳机制的作用
- 保持连接活跃:在 NAT(网络地址转换)和防火墙等网络环境下,连接可能会由于长时间没有数据传输而被断开。心跳机制通过定期发送小的数据包,确保连接持续活跃。
- 检测连接状态:心跳消息可以帮助判断连接是否仍然有效,以及对等体是否在线。这对于处理连接丢失或中断非常重要。
- 处理网络变化:当网络环境发生变化时,心跳机制可以帮助识别并重新建立连接。
2. 心跳机制的实现方式
- 定期消息:心跳机制通常通过定期发送特定格式的消息(如“ping”消息)实现。这些消息是轻量级的,不携带大量数据,仅用于检测连接状态。
- 应答机制:在发送心跳消息时,接收端会回复一个应答消息(如“pong”消息)。如果发送端在预期时间内没有收到应答,就可以认为连接可能出现了问题。
- 超时设置:心跳机制需要设置超时时间,决定在没有收到应答的情况下,多久之后认为连接失效。这需要根据实际应用场景来调整,以平衡连接检测的及时性和网络负担。
3. 流式系统中的心跳机制
- ICE(Interactive Connectivity Establishment):WebRTC 使用 ICE 协议来处理连接的建立和维护。ICE 包括了心跳机制,通过 STUN(Session Traversal Utilities for NAT)和 TURN(Traversal Using Relays around NAT)服务器帮助维持连接的稳定性。
- 数据通道心跳:WebRTC 的数据通道可以使用自定义的心跳机制来检测连接状态。通常会使用特定的消息类型(如
ping
和pong
)进行心跳检测。 - 库和框架:一些 WebRTC 库和框架可能已经实现了内置的心跳机制,开发者可以利用这些现成的功能来简化开发工作。
4. 心跳机制的配置和优化
- 调整频率:心跳的频率需要根据应用的需求来调整。频率过高可能会增加网络负担,频率过低则可能无法及时发现连接问题。
- 处理丢包:心跳机制需要具备处理数据包丢失的能力,例如,通过重试机制来处理丢失的心跳消息。
青龙流式系统的心跳的时序图
心跳的节奏从信令服务器,通过 Json传递到后端StreamerServer,然后通过底层的IoService进行双向消息传递。
目前的心跳中转是通过信令服务器的。
以下的代码是P2P连接成功建立后,我们建立了心跳的代码
KeepLiveMsg中的函数逻辑你可以自行修改,我们这里用Json封装了一个标准的消息体。
/// <summary> /// 连接成功后的回调 /// Only once called. /// </summary> /// <param name="sessionid"></param> void QLSignalConnection::OnConnected(int sessionid) { // mIOService.SetupHeartBeatCallback(QL::QLGlobalConfig::Get().HeartBeatInterval(), boost::bind(&QLSignalConnection::KeepAliveMsg, this)); QL_LOG(std::string("QLSignalConnection::OnConnected: Heart Enabled,interval:" + std::to_string(QL::QLGlobalConfig::Get().HeartBeatInterval())).c_str()); } /// <summary> /// 心跳 /// Streamer端发给信令Ping,前端返回pong, 在OnMessage函数中接收到。 /// 我们的网络层会开线程轮训。 /// /// </summary> void QLSignalConnection::KeepAliveMsg() { Json::Value msg; msg[MessageKeyName::type] = MessageTypeName::ping; msg[MessageKeyName::time] = timestamp(); SendMsgToSignalServer(msg); }