using UnityEngine;
namespace YouYou
{
/// <summary>
/// Socket组件
/// </summary>
public class SocketComponent : YouYouBaseComponent, IUpdateComponent
{
/// <summary>
/// Socket管理器
/// </summary>
private SocketManager m_SocketManager;
[Header("每帧最大发送数量")]
public int MaxSendCount = 5;
[Header("每次发包最大字节数量")]
public int MaxSendByteCount = 1024;
[Header("每帧最大接收数量")]
public int MaxReceiveCount = 5;
[Header("心跳间隔 秒")]
public int HeartbeatInterval = 10;
/// <summary>
/// 上次心跳时间
/// </summary>
private float m_PrevHeartbeatInterval = 0;
/// <summary>
/// PING值(毫秒)
/// </summary>
[HideInInspector]
public int PingValue;
/// <summary>
/// 游戏服务器的时间
/// </summary>
[HideInInspector]
public long GameServerTime;
/// <summary>
/// 和服务器对表的时刻
/// </summary>
[HideInInspector]
public float CheckServerTime;
/// <summary>
/// 当前是否处于连接状态
/// </summary>
private bool m_IsConnectToMainSocket = false;
/// <summary>
/// 发送数据的MemoryStream
/// </summary>
public MMO_MemoryStream SocketSendMS { get; private set; }
/// <summary>
/// 接收数据的MemoryStream
/// </summary>
public MMO_MemoryStream SocketReceiveMS { get; private set; }
protected override void OnAwake()
{
base.OnAwake();
GameEntry.RegisterUpdateComponent(this);
m_SocketManager = new SocketManager();
SocketSendMS = new MMO_MemoryStream();
SocketReceiveMS = new MMO_MemoryStream();
}
/// <summary>
/// 主Socket
/// </summary>
private SocketTcpRoutine m_MainSocket;
protected override void OnStart()
{
base.OnStart();
//创建Socket访问器
m_MainSocket = CreateSocketTcpRoutine();
//连接成功的回调
m_MainSocket.OnConnectOK = () =>
{
//已经建立了连接
m_IsConnectToMainSocket = true;
};
SocketProtoListener.AddProtoListener();
}
/// <summary>
/// 创建SocketTcp访问器
/// </summary>
/// <returns></returns>
public SocketTcpRoutine CreateSocketTcpRoutine()
{
//从对象池中取出访问器
return GameEntry.Pool.DequeueClassObject<SocketTcpRoutine>();
}
/// <summary>
/// 注册SocketTcp访问器进链表
/// </summary>
/// <param name="routine"></param>
internal void RegisterSocketTcpRoutine(SocketTcpRoutine routine)
{
m_SocketManager.RegisterSocketTcpRoutine(routine);
}
/// <summary>
/// 从链表移除SocketTcp访问器
/// </summary>
/// <param name="routine"></param>
internal void RemoveSocketTcpRoutine(SocketTcpRoutine routine)
{
m_SocketManager.RemoveSocketTcpRoutine(routine);
}
public void OnUpdate()
{
m_SocketManager.OnUpdate();
//如果建立连接
if (m_IsConnectToMainSocket)
{
//发送心跳 上次心跳时间 心跳间隔
if (Time.realtimeSinceStartup > m_PrevHeartbeatInterval + HeartbeatInterval)
{
//循环定时
m_PrevHeartbeatInterval = Time.realtimeSinceStartup;
//发送心跳
System_HeartbeatProto proto = new System_HeartbeatProto();
proto.LocalTime = Time.realtimeSinceStartup * 1000;
CheckServerTime = Time.realtimeSinceStartup;//和服务器的对表时刻
SendMainMsg(proto);
}
}
}
public override void Shutdown()
{
m_IsConnectToMainSocket = false;
m_SocketManager.Dispose();
//回池
GameEntry.Pool.EnqueueClassObject(m_MainSocket);
SocketProtoListener.RemoveProtoListener();
SocketSendMS.Dispose();
SocketSendMS.Close();
SocketReceiveMS.Dispose();
SocketReceiveMS.Close();
}
//=====================================
/// <summary>
/// 主Socket连接服务器
/// </summary>
/// <param name="ip"></param>
/// <param name="port"></param>
public void ConnectToMainSocket(string ip, int port)
{
m_MainSocket.Connect(ip, port);
}
/// <summary>
/// 主Socket发送消息
/// </summary>
/// <param name="buffer"></param>
public void SendMainMsg(byte[] buffer)
{
m_MainSocket.SendMsg(buffer);
}
/// <summary>
/// 主Socket发送消息
/// </summary>
/// <param name="buffer"></param>
public void SendMainMsg(IProto proto)
{
#if DEBUG_LOG_PROTO
Debug.Log("<color=#ffa200>发送消息:</color><color=#FFFB80>" + proto.ProtoEnName + " " + proto.ProtoCode + "</color>");
Debug.Log("<color=#ffdeb3>==>>" + JsonUtility.ToJson(proto) + "</color>");
#endif
m_MainSocket.SendMsg(proto.ToArray());
}
}
}
using UnityEngine;
using YouYou;
/// <summary>
/// 服务器返回心跳(工具只生成一次)
/// </summary>
public sealed class System_HeartbeatReturnHandler
{
public static void OnSystem_HeartbeatReturn(byte[] buffer)
{
System_HeartbeatReturnProto proto = System_HeartbeatReturnProto.GetProto(buffer);
#if DEBUG_LOG_PROTO
Debug.Log("<color=#00eaff>接收消息:</color><color=#00ff9c>" + proto.ProtoEnName + " " + proto.ProtoCode + "</color>");
Debug.Log("<color=#c5e1dc>==>>" + JsonUtility.ToJson(proto) + "</color>");
#endif
float localTime = proto.LocalTime;
long serverTime = proto.ServerTime;
//得到ping值
GameEntry.Socket.PingValue = (int)((Time.realtimeSinceStartup * 1000 - localTime) * 0.5f);
//得到本地计算的服务器时间
GameEntry.Socket.GameServerTime = serverTime - GameEntry.Socket.PingValue;
Debug.Log("服务器时间==" + GameEntry.Socket.GameServerTime);
Debug.Log("得到ping值==" + GameEntry.Socket.PingValue);
}
}
服务端