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;
}
}
}