c1_unity/Assets/Scripts/Common/Network/TCPService/TCPChannel.HeartBeat.cs
2023-06-16 21:33:43 +08:00

172 lines
5.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
/// <summary>
/// 心跳包同步的服务器当前时间戳 ms
/// </summary>
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);
}
/// <summary>
/// 检测接收的消息是否是心跳包
/// </summary>
/// <param name="incomingMessage"></param>
/// <returns>true: 是心跳包false: 其他消息</returns>
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;
}
/// <summary>
/// receive any message, reset heart beat status
/// </summary>
private void ResetHeartBeatStatus()
{
sendHeartBeatCount = 0;
lastSendHeartBeatTime = NetTime.Now;
}
/// <summary>
/// 设置上次心跳时间,立刻发送心跳
/// </summary>
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;
}
/// <summary>
/// @TODO Temp
/// </summary>
/// <returns></returns>
private byte[] SerializeHeartBeatReq()
{
byte[] data = {};
return data;
}
/// <summary>
/// @TODO Temp
/// </summary>
/// <param name="data"></param>
/// <param name="status"></param>
/// <returns></returns>
private bool DeserializeHeartBeatRsp(byte[] data, out long status, out long serverTimestamp)
{
serverTimestamp = 0;
status = 0;
return true;
}
}
}