NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Net/Client/NetClient.cs

191 lines
5.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

//////////////////////////////////////////////////////////////////////////
//
// 文件Assets/Code/Scripts/Gameplay/Net/Client/NetClient.cs
// 作者Xoen Xie
// 时间2023/07/18
// 描述:网络客户端
// 说明:
//
//////////////////////////////////////////////////////////////////////////
using UnityEngine;
using Framework;
using System;
namespace Gameplay.Net
{
public sealed class NetClient : INetHandler
{
private string m_sIP;
private int m_nPort;
private NetTcp m_Connection;
private NetReader m_Reader;
public bool m_bHandshake;
private float m_fLastHeartbeatTime = 0;
public uint mID;
private DH64 m_dh64;
private ulong m_nPrivateKey;
private ulong m_nPublicKey;
public NetClient()
{
m_Reader = new NetReader();
m_Connection = new NetTcp();
byte[] data = BitConverter.GetBytes((ulong)1234567890);
m_Connection.Cipher = new RC4Cipher(data);
m_dh64 = new DH64();
m_dh64.KeyPair(out m_nPrivateKey, out m_nPublicKey);
}
public bool Create(string sIP, int nPort)
{
m_sIP = sIP;
m_nPort = nPort;
m_Connection.Create(this);
m_bHandshake = false;
m_fLastHeartbeatTime = 0;
return true;
}
public void Release()
{
m_Connection.Release();
m_bHandshake = false;
}
public void DisConnect()
{
m_Connection.DisConnect();
}
public bool Connect()
{
if (!m_Connection.Connect(m_sIP, m_nPort))
{
return false;
}
Framework.EventManager.Instance.Send(Framework.EventManager.EventName.NetConnecting, mID);
return true;
}
public void SendMessage(IMessage message, uint nRawID = 0)
{
if (m_Connection == null || !m_Connection.mIsConnected)
{
DebugUtil.LogError("NetClient.SendMessage connection not connected, msg id={0}", message.ID);
return;
}
m_Connection.Send((ushort)message.ID, message.Export(), nRawID);
}
public void Update()
{
m_Connection.Dispath();
if (!m_Connection.mIsConnected)
return;
if (m_bHandshake)
{
float fCurTime = Time.realtimeSinceStartup;
if (fCurTime >= Constants.HEARTBEAT_INTERVAL + m_fLastHeartbeatTime)
{
m_fLastHeartbeatTime = fCurTime;
SendHeartbeat();
}
}
}
public void OnConnected()
{
Framework.EventManager.Instance.Send(Framework.EventManager.EventName.NetConnected, mID);
DebugUtil.Log("NetClient::OnConnected ip={0}, port={1}", m_sIP, m_nPort);
// 连接成功发送握手消息
SendHandshake();
m_fLastHeartbeatTime = 0;
}
public void OnRecv(byte[] data)
{
m_Reader.Init(data);
ushort nMsgID = 0;
m_Reader.ReadUShort(out nMsgID);
//减少心跳包的Log
if ((NLDMID.MSGID)nMsgID != NLDMID.MSGID.GtCltHeartbeat)
{
DebugUtil.Log("NetClient OnRecv, msg id={0}", (NLDMID.MSGID)nMsgID);
}
IMessage message = NetManager.Instance.GetMessage((NLDMID.MSGID)nMsgID);
if (message != null)
{
message.Import(data, 2, data.Length - 2);
message.Execute(this);
}
else
{
DebugUtil.LogError("NetClient OnRecv message not found, msg id={0}", (NLDMID.MSGID)nMsgID);
}
}
public void OnError(NetError nErrorCode)
{
DebugUtil.LogError("NetClient::OnError, 网络出错,错误码={0}", nErrorCode);
Framework.EventManager.Instance.Send(Framework.EventManager.EventName.NetError, mID);
}
private void SendHandshake()
{
var msg = NetManager.Instance.GetMessage(NLDMID.MSGID.CltGtHandshake) as MSG_Clt_Gt_Handshake;
msg.mPB.ClientPublicKey = m_nPublicKey;
SendMessage(NetManager.Instance.GetMessage(NLDMID.MSGID.CltGtHandshake));
}
public void SendHeartbeat()
{
MSG_Clt_Gt_Heartbeat msg = NetManager.Instance.GetMessage(NLDMID.MSGID.CltGtHeartbeat) as MSG_Clt_Gt_Heartbeat;
msg.mPB.Time = PhxhSDK.Utils.GetTimeStampMilliseconds();
SendMessage(msg);
}
public void OnHandshake(ulong nServerPublicKey)
{
var secret = m_dh64.Secret(m_nPrivateKey, nServerPublicKey);
byte[] data = BitConverter.GetBytes(secret);
m_Connection.Cipher = new RC4Cipher(data);
DebugUtil.Log("NetClient.OnHandshake start ...");
Framework.EventManager.Instance.Send(Framework.EventManager.EventName.NetHandshakeDone, mID);
m_bHandshake = true;
}
}
}