using System; using System.Collections.Generic; using System.Text; using Facebook.MiniJSON; namespace BF { internal partial class TCPChannel { private const uint HeartBeat_Req_Group = 3763117270; private const uint HeartBeat_Rsp_Group = 3763119103; // private const byte HeartBeat_Req_Cmd = 2; private const int HeartBeat_Rsp_OK = 0; // 上一次发送心跳包的时间 private double lastSendHeartBeatTime = 0; //已发送心跳包的数量;接收到任意返回心跳包就重置 private int sendHeartBeatCount = 0; //不发心跳包的最长时间,超过这个时间,就开始重连(因为某些原因,造成网络线程暂停,此时需要这个逻辑) private float maxHeartBeatMissTime = 0; /// /// 心跳包同步的服务器当前时间戳 ms /// private long serverTimestamp; private void InitializeHeartBeat() { maxHeartBeatMissTime = ownerConnection.configuration.HeartBeatInterval * ownerConnection.configuration.MaxHeartBeatMissCount; ResetHeartBeatStatus(); } private void HeartBeat() { if (!ownerConnection.configuration.EnableHeartBeat) { return; } if (actualStatus != NetConnectStatus.Connected) { return; } var nowSecond = NetTime.Now; ////距离上一次发送心跳包的时间 var waitHeartBeatInterval = nowSecond - lastSendHeartBeatTime; if (waitHeartBeatInterval < ownerConnection.configuration.HeartBeatInterval) { return; } SendHeartBeat(nowSecond, waitHeartBeatInterval); } /// /// 检测接收的消息是否是心跳包 /// /// /// true: 是心跳包;false: 其他消息 private bool FilterHeartBeatIncomingMessage(NetIncomingMessage incomingMessage) { if (incomingMessage.Group != HeartBeat_Rsp_Group) { return false; } //receive heart beat success ResetHeartBeatStatus(); this.serverTimestamp = 0; //release heartbeat message var heartbeatMessage = ownerConnection.CreateIncomingMessage(NetIncomingMessageType.HeartBeatMessage, null); heartbeatMessage.HeartbeatSyncTimestamp = this.serverTimestamp; ReleaseMessage(heartbeatMessage); LogDebug("Heart beat success !!!"); return true; } /// /// receive any message, reset heart beat status /// private void ResetHeartBeatStatus() { sendHeartBeatCount = 0; lastSendHeartBeatTime = NetTime.Now; } /// /// 设置上次心跳时间,立刻发送心跳 /// private void ForceSendHeartBeatImmediately() { // lastSendHeartBeatTime = NetTime.Now - ownerConnection.configuration.HeartBeatInterval - 1; lastSendHeartBeatTime = NetTime.Now; } private void SendHeartBeat(double nowSecond, double waitHeartBeatInterval) { if (actualStatus != NetConnectStatus.Connected) { return; } sendHeartBeatCount += 1; //miss heart beat message to many, try reconnect. if (sendHeartBeatCount > ownerConnection.configuration.MaxHeartBeatMissCount) { LogDebug("Miss heart beat max count, try reconnect."); StartSmartReconnectCountdown(); ResetHeartBeatStatus(); return; } // 如果两次心跳包之间的时间间隔,超过了最大心跳次数的间隔,开始重连; // 因为某些原因,造成网络线程暂停,此时需要这个逻辑; if (waitHeartBeatInterval > maxHeartBeatMissTime) { LogDebug("Miss heart beat max time, try reconnect."); StartSmartReconnectCountdown(); ResetHeartBeatStatus(); return; } var heartBeat = CreateHeartBeatOutgoingMessage(); SendInternal(heartBeat); lastSendHeartBeatTime = nowSecond; LogDebug("Begin send heart beat !!!"); } private NetOutgoingMessage CreateHeartBeatOutgoingMessage() { var message = ownerConnection.CreateOutgoingMessage(NetOutgoingMessageType.UserData); var heartBeatData = SerializeHeartBeatReq(); message.Encode(HeartBeat_Req_Group, 0, heartBeatData); return message; } /// /// @TODO Temp /// /// private byte[] SerializeHeartBeatReq() { byte[] data = {}; return data; } /// /// @TODO Temp /// /// /// /// private bool DeserializeHeartBeatRsp(byte[] data, out long status, out long serverTimestamp) { serverTimestamp = 0; status = 0; return true; } } }