mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
提交网络模块TCP 超时重连机制
提交网络模块TCP 超时重连机制
This commit is contained in:
@@ -41,6 +41,7 @@ public class TEngineUI : UIWindow
|
|||||||
|
|
||||||
protected override void OnUpdate()
|
protected override void OnUpdate()
|
||||||
{
|
{
|
||||||
|
TEngineHotUpdate.GameLogicMain.Update();
|
||||||
TLogger.LogInfo("TEngineUI OnUpdate");
|
TLogger.LogInfo("TEngineUI OnUpdate");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
using TEngineCore;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
|
|
||||||
namespace TEngineHotUpdate
|
namespace TEngineHotUpdate
|
||||||
{
|
{
|
||||||
@@ -12,32 +6,32 @@ namespace TEngineHotUpdate
|
|||||||
{
|
{
|
||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
{
|
||||||
Debug.Log("Init");
|
GameTime.StartFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Start()
|
public static void Start()
|
||||||
{
|
{
|
||||||
Debug.Log("Start");
|
GameTime.StartFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Update()
|
public static void Update()
|
||||||
{
|
{
|
||||||
Debug.Log("Update");
|
GameTime.StartFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LateUpdate()
|
public static void LateUpdate()
|
||||||
{
|
{
|
||||||
Debug.Log("LateUpdate");
|
GameTime.StartFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Destroy()
|
public static void Destroy()
|
||||||
{
|
{
|
||||||
|
GameTime.StartFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnApplicationPause(bool isPause)
|
public static void OnApplicationPause(bool isPause)
|
||||||
{
|
{
|
||||||
|
GameTime.StartFrame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="15.0"
|
||||||
|
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
@@ -56,6 +57,12 @@
|
|||||||
<Reference Include="UnityEngine.InputLegacyModule">
|
<Reference Include="UnityEngine.InputLegacyModule">
|
||||||
<HintPath>UnityLib\UnityEngine.InputLegacyModule.dll</HintPath>
|
<HintPath>UnityLib\UnityEngine.InputLegacyModule.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="protobuf-net">
|
||||||
|
<HintPath>UnityLib\protobuf-net.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="protobuf-net">
|
||||||
|
<HintPath>UnityLib\Google.Protobuf.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
<Reference Include="System.Net.Http" />
|
<Reference Include="System.Net.Http" />
|
||||||
@@ -68,6 +75,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="src\GameLogic\" />
|
<Folder Include="src\GameLogic\" />
|
||||||
|
<Folder Include="src\Proto\" />
|
||||||
<Folder Include="src\TEngineCore\3rd\" />
|
<Folder Include="src\TEngineCore\3rd\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
BIN
TEngineHotUpdate/UnityLib/Google.Protobuf.dll
Normal file
BIN
TEngineHotUpdate/UnityLib/Google.Protobuf.dll
Normal file
Binary file not shown.
BIN
TEngineHotUpdate/UnityLib/protobuf-net.dll
Normal file
BIN
TEngineHotUpdate/UnityLib/protobuf-net.dll
Normal file
Binary file not shown.
2104
TEngineHotUpdate/src/Proto/TEngineProto.cs
Normal file
2104
TEngineHotUpdate/src/Proto/TEngineProto.cs
Normal file
File diff suppressed because it is too large
Load Diff
31
TEngineHotUpdate/src/TEngineCore/Core/GameTime.cs
Normal file
31
TEngineHotUpdate/src/TEngineCore/Core/GameTime.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace TEngineCore
|
||||||
|
{
|
||||||
|
public static class GameTime
|
||||||
|
{
|
||||||
|
public static void StartFrame()
|
||||||
|
{
|
||||||
|
time = Time.time;
|
||||||
|
deltaTime = Time.deltaTime;
|
||||||
|
quickRealTime = Time.realtimeSinceStartup;
|
||||||
|
frameCount = Time.frameCount;
|
||||||
|
unscaledTime = Time.unscaledTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float time;
|
||||||
|
public static float deltaTime;
|
||||||
|
public static int frameCount;
|
||||||
|
public static float unscaledTime;
|
||||||
|
|
||||||
|
public static float realtimeSinceStartup
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Time.realtimeSinceStartup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float quickRealTime;
|
||||||
|
}
|
||||||
|
}
|
166
TEngineHotUpdate/src/TEngineCore/Net/ClientConnectWatcher.cs
Normal file
166
TEngineHotUpdate/src/TEngineCore/Net/ClientConnectWatcher.cs
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
namespace TEngineCore.Net
|
||||||
|
{
|
||||||
|
enum ClientConnectWatcherStatus
|
||||||
|
{
|
||||||
|
StatusInit,
|
||||||
|
StatusReconnectAuto,
|
||||||
|
StatusReconnectConfirm,
|
||||||
|
StatusWaitExit
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClientConnectWatcher
|
||||||
|
{
|
||||||
|
#region Propreties
|
||||||
|
private GameClient m_client;
|
||||||
|
private float m_statusTime;
|
||||||
|
private int m_reconnetCnt = 0;
|
||||||
|
private int m_disconnectReason = 0;
|
||||||
|
private ClientConnectWatcherStatus m_status = ClientConnectWatcherStatus.StatusInit;
|
||||||
|
|
||||||
|
private bool m_enable = false;
|
||||||
|
public bool Enable
|
||||||
|
{
|
||||||
|
get { return m_enable; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (m_enable != value)
|
||||||
|
{
|
||||||
|
m_enable = value;
|
||||||
|
if (m_enable)
|
||||||
|
{
|
||||||
|
OnEnable();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OnDisable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientConnectWatcherStatus Status
|
||||||
|
{
|
||||||
|
get { return m_status; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (m_status != value)
|
||||||
|
{
|
||||||
|
m_status = value;
|
||||||
|
m_statusTime = GameTime.time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public ClientConnectWatcher(GameClient client)
|
||||||
|
{
|
||||||
|
m_client = client;
|
||||||
|
m_statusTime = GameTime.time;
|
||||||
|
m_status = ClientConnectWatcherStatus.StatusInit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update()
|
||||||
|
{
|
||||||
|
if (!m_enable)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_client.IsEntered)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (m_status)
|
||||||
|
{
|
||||||
|
case ClientConnectWatcherStatus.StatusInit:
|
||||||
|
UpdateOnInitStatus();
|
||||||
|
break;
|
||||||
|
case ClientConnectWatcherStatus.StatusReconnectAuto:
|
||||||
|
UpdateOnReconnectAuto();
|
||||||
|
break;
|
||||||
|
case ClientConnectWatcherStatus.StatusReconnectConfirm:
|
||||||
|
UpdateOnReconnectConfirm();
|
||||||
|
break;
|
||||||
|
case ClientConnectWatcherStatus.StatusWaitExit:
|
||||||
|
UpdateOnWaitExit();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnReConnect()
|
||||||
|
{
|
||||||
|
if (m_status == ClientConnectWatcherStatus.StatusReconnectConfirm)
|
||||||
|
{
|
||||||
|
Status = ClientConnectWatcherStatus.StatusReconnectAuto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateOnInitStatus()
|
||||||
|
{
|
||||||
|
if (m_reconnetCnt <= 2)
|
||||||
|
{
|
||||||
|
if (m_reconnetCnt == 0)
|
||||||
|
{
|
||||||
|
m_disconnectReason = m_client.LastNetErrCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = ClientConnectWatcherStatus.StatusReconnectAuto;
|
||||||
|
m_reconnetCnt++;
|
||||||
|
|
||||||
|
//Reconnect
|
||||||
|
m_client.Reconnect();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = ClientConnectWatcherStatus.StatusReconnectConfirm;
|
||||||
|
m_reconnetCnt++;
|
||||||
|
|
||||||
|
//var window = UISys.Mgr.ShowWindow<Tip_NetError>();
|
||||||
|
//window.SetErrCode(m_disconnectReason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateOnReconnectAuto()
|
||||||
|
{
|
||||||
|
if (m_client.IsEntered)
|
||||||
|
{
|
||||||
|
Status = ClientConnectWatcherStatus.StatusInit;
|
||||||
|
m_reconnetCnt = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float nowTime = GameTime.time;
|
||||||
|
if (m_statusTime + 5 < nowTime)
|
||||||
|
{
|
||||||
|
//切换到默认的,下一帧继续判断是否需要自动还是手动
|
||||||
|
Status = ClientConnectWatcherStatus.StatusInit;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateOnReconnectConfirm()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateOnWaitExit()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDisable()
|
||||||
|
{
|
||||||
|
Status = ClientConnectWatcherStatus.StatusInit;
|
||||||
|
m_reconnetCnt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
Status = ClientConnectWatcherStatus.StatusInit;
|
||||||
|
m_reconnetCnt = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,118 @@
|
|||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
|
||||||
|
namespace TEngineCore.Net
|
||||||
|
{
|
||||||
|
public enum ClientSocketEventType
|
||||||
|
{
|
||||||
|
EventConnected,
|
||||||
|
EventConnectFail,
|
||||||
|
EventDisconnected,
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IClientSocket
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 是否连接了
|
||||||
|
/// </summary>
|
||||||
|
bool IsConnected { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否是流协议
|
||||||
|
/// </summary>
|
||||||
|
bool IsStream { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 心跳间隔
|
||||||
|
/// </summary>
|
||||||
|
int HeartBeatInterval { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 本地绑定地址
|
||||||
|
/// </summary>
|
||||||
|
EndPoint LocalAddr { get; }
|
||||||
|
|
||||||
|
SocketError LastSockError { get; }
|
||||||
|
|
||||||
|
string LastErrDesc { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册系统事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handler"></param>
|
||||||
|
void RegEventHandle(Action<ClientSocketEventType> handler);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 连接请求
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="server"></param>
|
||||||
|
/// <param name="port"></param>
|
||||||
|
/// <param name="iTimeout"></param>
|
||||||
|
/// <param name="retryNum"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool Connect(string server, int port, int iTimeout, int retryNum);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关闭连接
|
||||||
|
/// </summary>
|
||||||
|
void Close();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关闭连接
|
||||||
|
/// </summary>
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送数据
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool Send(byte[] data, int offset, int len);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送快捷数据,不用保证丢包
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
/// <param name="offset"></param>
|
||||||
|
/// <param name="len"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool SendUdpTypeData(byte[] data, int offset, int len);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否支持udp的包
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool IsSupportUdpType();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 收包处理
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="buf"></param>
|
||||||
|
/// <param name="iOffset"></param>
|
||||||
|
/// <param name="maxSize"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
int Recv(byte[] buf, int iOffset, int maxSize);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 循环调用
|
||||||
|
/// </summary>
|
||||||
|
void Update();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最后一帧,保证肯定要包发出去,减少延迟
|
||||||
|
/// </summary>
|
||||||
|
void LateUpdate();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取写队列的个数
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
int GetSendQueueCount();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 像底层注册错误打印,当缓冲区满之类的,调用上层的统计来打印
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="debugCmd"></param>
|
||||||
|
void RegDebugCmdHandle(Action debugCmd);
|
||||||
|
}
|
||||||
|
}
|
117
TEngineHotUpdate/src/TEngineCore/Net/ClientSocket/Message.cs
Normal file
117
TEngineHotUpdate/src/TEngineCore/Net/ClientSocket/Message.cs
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using TEngineProto;
|
||||||
|
|
||||||
|
namespace TEngineCore.Net
|
||||||
|
{
|
||||||
|
public class Message
|
||||||
|
{
|
||||||
|
private const int BufferHead = 4;
|
||||||
|
|
||||||
|
private static byte[] buffer = new byte[1024];
|
||||||
|
|
||||||
|
private int startindex;
|
||||||
|
|
||||||
|
public byte[] Buffer
|
||||||
|
{
|
||||||
|
get { return buffer; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int StartIndex
|
||||||
|
{
|
||||||
|
get { return startindex; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Remsize
|
||||||
|
{
|
||||||
|
get { return buffer.Length - startindex; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReadBuffer(byte[] bufBytes, Action<MainPack> handleResponse = null)
|
||||||
|
{
|
||||||
|
var length = bufBytes.Length;
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
Buffer[i] = bufBytes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
startindex += length;
|
||||||
|
|
||||||
|
if (startindex <= BufferHead)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = length - BufferHead;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (startindex >= (count + BufferHead))
|
||||||
|
{
|
||||||
|
MainPack pack = (MainPack)MainPack.Descriptor.Parser.ParseFrom(buffer, BufferHead, count);
|
||||||
|
|
||||||
|
if (handleResponse != null)
|
||||||
|
{
|
||||||
|
handleResponse(pack);
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.Copy(buffer, length, buffer, 0, startindex - length);
|
||||||
|
|
||||||
|
startindex -= length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReadBuffer(int length, Action<MainPack> handleResponse = null)
|
||||||
|
{
|
||||||
|
startindex += length;
|
||||||
|
|
||||||
|
if (startindex <= BufferHead)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = length - BufferHead;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (startindex >= (count + BufferHead))
|
||||||
|
{
|
||||||
|
MainPack pack = (MainPack)MainPack.Descriptor.Parser.ParseFrom(buffer, BufferHead, count);
|
||||||
|
|
||||||
|
if (handleResponse != null)
|
||||||
|
{
|
||||||
|
handleResponse(pack);
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.Copy(buffer, length, buffer, 0, startindex - length);
|
||||||
|
|
||||||
|
startindex -= length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] PackData(MainPack pack)
|
||||||
|
{
|
||||||
|
byte[] data = pack.ToByteArray();
|
||||||
|
byte[] head = BitConverter.GetBytes(data.Length);
|
||||||
|
return head.Concat(data).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] PackDataUdp(MainPack pack)
|
||||||
|
{
|
||||||
|
return pack.ToByteArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,120 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using TEngineProto;
|
||||||
|
|
||||||
|
|
||||||
|
namespace TEngineCore.Net
|
||||||
|
{
|
||||||
|
public class TcpConnection
|
||||||
|
{
|
||||||
|
private Socket socket;
|
||||||
|
private string m_Host;
|
||||||
|
private int m_Port;
|
||||||
|
private Message message;
|
||||||
|
private GameClient gameClient;
|
||||||
|
|
||||||
|
public TcpConnection(GameClient gameClient)
|
||||||
|
{
|
||||||
|
message = new Message();
|
||||||
|
this.gameClient = gameClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Connect(string host, int port)
|
||||||
|
{
|
||||||
|
if (socket == null)
|
||||||
|
{
|
||||||
|
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (socket.Connected)
|
||||||
|
{
|
||||||
|
socket.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TLogger.LogInfo("start connect server[{0}:{1}]...", host, port);
|
||||||
|
|
||||||
|
gameClient.Status = GameClientStatus.StatusInit;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
socket.Connect(host, port);
|
||||||
|
StartReceive();
|
||||||
|
gameClient.Status = GameClientStatus.StatusConnect;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
TLogger.LogError(e.Message);
|
||||||
|
TLogger.LogError("socket connect {0}:{1} failed", host, port);
|
||||||
|
//ChangeStateOnEnterFail();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_Host = host;
|
||||||
|
m_Port = port;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartReceive()
|
||||||
|
{
|
||||||
|
socket.BeginReceive(message.Buffer, message.StartIndex, message.Remsize, SocketFlags.None, ReceiveCallback, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReceiveCallback(IAsyncResult asyncResult)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (socket == null || socket.Connected == false)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Length = socket.EndReceive(asyncResult);
|
||||||
|
|
||||||
|
if (Length == 0)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
message.ReadBuffer(Length, gameClient.HandleResponse);
|
||||||
|
|
||||||
|
StartReceive();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
TLogger.LogError("TcpConnection DisConnected: " + e);
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SendCsMsg(MainPack mainPack)
|
||||||
|
{
|
||||||
|
if (socket == null || socket.Connected == false)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
socket.Send(Message.PackData(mainPack));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
TLogger.LogError("TcpConnection SendCsMsg: " + e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
if (socket != null && socket.Connected)
|
||||||
|
{
|
||||||
|
socket.Close();
|
||||||
|
}
|
||||||
|
gameClient.Status = GameClientStatus.StatusInit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace TEngineCore.Net
|
||||||
|
{
|
||||||
|
public class UdpConnection
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
42
TEngineHotUpdate/src/TEngineCore/Net/DataCenterSys.cs
Normal file
42
TEngineHotUpdate/src/TEngineCore/Net/DataCenterSys.cs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace TEngineCore.Net
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 数据中心系统
|
||||||
|
/// </summary>
|
||||||
|
public class DataCenterSys : BaseLogicSys<DataCenterSys>
|
||||||
|
{
|
||||||
|
private List<IDataCenterModule> m_listModule = new List<IDataCenterModule>();
|
||||||
|
|
||||||
|
public override bool OnInit()
|
||||||
|
{
|
||||||
|
RegCmdHandle();
|
||||||
|
InitModule();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RegCmdHandle()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitModule()
|
||||||
|
{
|
||||||
|
//InitModule(LoginDataMgr.Instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InitModule(IDataCenterModule module)
|
||||||
|
{
|
||||||
|
if (!m_listModule.Contains(module))
|
||||||
|
{
|
||||||
|
module.Init();
|
||||||
|
m_listModule.Add(module);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
568
TEngineHotUpdate/src/TEngineCore/Net/GameClient.cs
Normal file
568
TEngineHotUpdate/src/TEngineCore/Net/GameClient.cs
Normal file
@@ -0,0 +1,568 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using TEngineProto;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace TEngineCore.Net
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 客户端状态
|
||||||
|
/// </summary>
|
||||||
|
public enum GameClientStatus
|
||||||
|
{
|
||||||
|
StatusInit, //初始化
|
||||||
|
StatusReconnect, //重新连接
|
||||||
|
StatusClose, //断开连接
|
||||||
|
StatusConnect, //连接中
|
||||||
|
StatusEnter, //Login登录成功
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void CsMsgDelegate(MainPack mainPack);
|
||||||
|
|
||||||
|
public class GameClient:TSingleton<GameClient>
|
||||||
|
{
|
||||||
|
|
||||||
|
#region Propriety
|
||||||
|
|
||||||
|
#region TimeOutCheck
|
||||||
|
private const int CHECK_TIMEOUT_PERFRAME = 10;
|
||||||
|
const int MAX_MSG_HANDLE = 256;
|
||||||
|
UInt32 m_dwLastCheckIndex = 0;
|
||||||
|
CsMsgDelegate[] m_aMsgHandles = new CsMsgDelegate[MAX_MSG_HANDLE];
|
||||||
|
float[] m_fMsgRegTime = new float[MAX_MSG_HANDLE];
|
||||||
|
private float m_timeout = 15;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private string m_lastHost = null;
|
||||||
|
private int m_lastPort = 0;
|
||||||
|
private GameClientStatus m_status = GameClientStatus.StatusInit;
|
||||||
|
/// <summary>
|
||||||
|
/// GameClient状态
|
||||||
|
/// </summary>
|
||||||
|
public GameClientStatus Status
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_status;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
m_status = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最新连接错误的时间
|
||||||
|
/// </summary>
|
||||||
|
private float m_lastLogDisconnectErrTime = 0f;
|
||||||
|
/// <summary>
|
||||||
|
/// 最新的错误码
|
||||||
|
/// </summary>
|
||||||
|
private int m_lastNetErrCode = 0;
|
||||||
|
/// <summary>
|
||||||
|
/// 最近一次心跳的时间
|
||||||
|
/// </summary>
|
||||||
|
private float m_lastHbTime = 0f;
|
||||||
|
/// <summary>
|
||||||
|
/// 心跳间隔
|
||||||
|
/// </summary>
|
||||||
|
private const float m_heartBeatDurTime = 15;
|
||||||
|
/// <summary>
|
||||||
|
/// 连续心跳超时
|
||||||
|
/// </summary>
|
||||||
|
private int m_heatBeatTimeoutNum = 0;
|
||||||
|
private int m_ping = -1;
|
||||||
|
public bool IsEntered
|
||||||
|
{
|
||||||
|
get { return m_status == GameClientStatus.StatusEnter; }
|
||||||
|
}
|
||||||
|
public bool IsNetworkOkAndLogined
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_status == GameClientStatus.StatusEnter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LastNetErrCode
|
||||||
|
{
|
||||||
|
get { return m_lastNetErrCode; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private ClientConnectWatcher m_connectWatcher;
|
||||||
|
|
||||||
|
private void ResetParam()
|
||||||
|
{
|
||||||
|
m_lastLogDisconnectErrTime = 0f;
|
||||||
|
m_heatBeatTimeoutNum = 0;
|
||||||
|
m_lastHbTime = 0f;
|
||||||
|
m_ping = -1;
|
||||||
|
m_lastNetErrCode = 0;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private TcpConnection m_connect;
|
||||||
|
|
||||||
|
public GameClient()
|
||||||
|
{
|
||||||
|
m_connect = new TcpConnection(this);
|
||||||
|
m_connectWatcher = new ClientConnectWatcher(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Connect(string host, int port, bool reconnect = false)
|
||||||
|
{
|
||||||
|
ResetParam();
|
||||||
|
if (!reconnect)
|
||||||
|
{
|
||||||
|
SetWatchReconnect(false);
|
||||||
|
}
|
||||||
|
//GameEventMgr.Instance.Send(ShowWaitingUI);
|
||||||
|
m_lastHost = host;
|
||||||
|
m_lastPort = port;
|
||||||
|
Status = reconnect ? GameClientStatus.StatusReconnect : GameClientStatus.StatusInit;
|
||||||
|
TLogger.LogWarning("Start connect server {0}:{1} Reconnect:{2}", host, port, reconnect);
|
||||||
|
return m_connect.Connect(host, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Shutdown()
|
||||||
|
{
|
||||||
|
m_connect.Close();
|
||||||
|
m_status = GameClientStatus.StatusInit;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 发送网络消息
|
||||||
|
/// <summary>
|
||||||
|
/// 发送消息包
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reqPkg"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool SendCsMsg(MainPack reqPkg)
|
||||||
|
{
|
||||||
|
if (!CheckPack(reqPkg))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return DoSendData(reqPkg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送消息包并注册回调
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pack"></param>
|
||||||
|
/// <param name="resHandler"></param>
|
||||||
|
/// <param name="needShowWaitUI"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool SendCsMsg(MainPack pack, CsMsgDelegate resHandler = null, bool needShowWaitUI = true)
|
||||||
|
{
|
||||||
|
if (!CheckPack(pack))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ret = DoSendData(pack);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
TLogger.LogError("SendCSMsg Error");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (resHandler != null)
|
||||||
|
{
|
||||||
|
RegTimeOutHandle((uint)pack.Actioncode, resHandler);
|
||||||
|
RegActionHandle((int)pack.Actioncode, resHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool DoSendData(MainPack reqPkg)
|
||||||
|
{
|
||||||
|
var sendRet = m_connect.SendCsMsg(reqPkg);
|
||||||
|
|
||||||
|
return sendRet;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 网络消息回调,非主线程
|
||||||
|
Dictionary<int, List<CsMsgDelegate>> m_mapCmdHandle = new Dictionary<int, List<CsMsgDelegate>>();
|
||||||
|
/// <summary>
|
||||||
|
/// 委托缓存堆栈
|
||||||
|
/// </summary>
|
||||||
|
private Queue<List<CsMsgDelegate>> cachelistHandle = new Queue<List<CsMsgDelegate>>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 消息包缓存堆栈
|
||||||
|
/// </summary>
|
||||||
|
private Queue<MainPack> queuepPacks = new Queue<MainPack>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 网络消息回调,非主线程
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pack"></param>
|
||||||
|
public void HandleResponse(MainPack pack)
|
||||||
|
{
|
||||||
|
lock (cachelistHandle)
|
||||||
|
{
|
||||||
|
List<CsMsgDelegate> listHandle;
|
||||||
|
|
||||||
|
if (m_mapCmdHandle.TryGetValue((int)pack.Actioncode, out listHandle))
|
||||||
|
{
|
||||||
|
cachelistHandle.Enqueue(listHandle);
|
||||||
|
|
||||||
|
queuepPacks.Enqueue(pack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Udp网络消息回调,非主线程
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pack"></param>
|
||||||
|
private void UdpHandleResponse(MainPack pack)
|
||||||
|
{
|
||||||
|
//Debug.Log(pack);
|
||||||
|
List<CsMsgDelegate> listHandle;
|
||||||
|
|
||||||
|
if (m_mapCmdHandle.TryGetValue((int)pack.Actioncode, out listHandle))
|
||||||
|
{
|
||||||
|
foreach (CsMsgDelegate handle in listHandle)
|
||||||
|
{
|
||||||
|
handle(pack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 注册网络消息回调
|
||||||
|
/// <summary>
|
||||||
|
/// 注册静态消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="iCmdID"></param>
|
||||||
|
/// <param name="msgDelegate"></param>
|
||||||
|
public void RegActionHandle(int actionId, CsMsgDelegate msgDelegate)
|
||||||
|
{
|
||||||
|
List<CsMsgDelegate> listHandle;
|
||||||
|
if (!m_mapCmdHandle.TryGetValue(actionId, out listHandle))
|
||||||
|
{
|
||||||
|
listHandle = new List<CsMsgDelegate>();
|
||||||
|
m_mapCmdHandle[actionId] = listHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listHandle != null)
|
||||||
|
{
|
||||||
|
if (listHandle.Contains(msgDelegate))
|
||||||
|
{
|
||||||
|
Debug.LogFormat("-------------repeat RegCmdHandle ActionCode:{0}-----------", (ActionCode)actionId);
|
||||||
|
}
|
||||||
|
listHandle.Add(msgDelegate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 注册Udp静态消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="iCmdID"></param>
|
||||||
|
/// <param name="msgDelegate"></param>
|
||||||
|
public void UdpRegActionHandle(int actionId, CsMsgDelegate msgDelegate)
|
||||||
|
{
|
||||||
|
List<CsMsgDelegate> listHandle;
|
||||||
|
if (!m_mapCmdHandle.TryGetValue(actionId, out listHandle))
|
||||||
|
{
|
||||||
|
listHandle = new List<CsMsgDelegate>();
|
||||||
|
m_mapCmdHandle[actionId] = listHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listHandle != null)
|
||||||
|
{
|
||||||
|
if (listHandle.Contains(msgDelegate))
|
||||||
|
{
|
||||||
|
Debug.LogFormat("-------------repeat RegCmdHandle ActionCode:{0}-----------", (ActionCode)actionId);
|
||||||
|
}
|
||||||
|
listHandle.Add(msgDelegate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移除消息处理函数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cmdId"></param>
|
||||||
|
/// <param name="msgDelegate"></param>
|
||||||
|
public void RmvCmdHandle(int actionId, CsMsgDelegate msgDelegate)
|
||||||
|
{
|
||||||
|
List<CsMsgDelegate> listHandle;
|
||||||
|
if (!m_mapCmdHandle.TryGetValue(actionId, out listHandle))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listHandle != null)
|
||||||
|
{
|
||||||
|
listHandle.Remove(msgDelegate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CheckPack(MainPack pack)
|
||||||
|
{
|
||||||
|
if (pack == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pack.Actioncode == ActionCode.ActionNone)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pack.Requestcode == RequestCode.RequestNone)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 心跳处理
|
||||||
|
protected bool CheckHeatBeatTimeout()
|
||||||
|
{
|
||||||
|
if (m_heatBeatTimeoutNum >= 2)
|
||||||
|
{
|
||||||
|
Shutdown();
|
||||||
|
m_heatBeatTimeoutNum = 0;
|
||||||
|
Status = GameClientStatus.StatusClose;
|
||||||
|
TLogger.LogError("heat beat detect timeout");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TickHeartBeat()
|
||||||
|
{
|
||||||
|
if (Status != GameClientStatus.StatusEnter)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var nowTime = GameTime.realtimeSinceStartup;
|
||||||
|
if (m_lastHbTime + m_heartBeatDurTime < nowTime)
|
||||||
|
{
|
||||||
|
m_lastHbTime = nowTime;
|
||||||
|
MainPack pack = new MainPack
|
||||||
|
{
|
||||||
|
Actioncode = ActionCode.HeartBeat
|
||||||
|
};
|
||||||
|
GameClient.Instance.SendCsMsg(pack, HandleHeatBeatRes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleHeatBeatRes(MainPack mainPack)
|
||||||
|
{
|
||||||
|
if (mainPack.Returncode != ReturnCode.Success)
|
||||||
|
{
|
||||||
|
//如果是超时了,则标记最近收到包的次数
|
||||||
|
if (mainPack.Returncode == ReturnCode.MsgTimeOut)
|
||||||
|
{
|
||||||
|
m_heatBeatTimeoutNum++;
|
||||||
|
TLogger.LogError("heat beat timeout: {0}", m_heatBeatTimeoutNum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float diffTime = GameTime.realtimeSinceStartup - mainPack.HeatEchoTime;
|
||||||
|
m_ping = (int)(diffTime * 1000);
|
||||||
|
m_heatBeatTimeoutNum = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清理所有的网络消息
|
||||||
|
/// </summary>
|
||||||
|
public void CleanAllNetMsg()
|
||||||
|
{
|
||||||
|
m_mapCmdHandle.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reconnect()
|
||||||
|
{
|
||||||
|
m_connectWatcher.OnReConnect();
|
||||||
|
Connect(m_lastHost, m_lastPort, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnUpdate()
|
||||||
|
{
|
||||||
|
HandleCsMsgOnUpdate();
|
||||||
|
CheckCsMsgTimeOut();
|
||||||
|
TickHeartBeat();
|
||||||
|
CheckHeatBeatTimeout();
|
||||||
|
m_connectWatcher.Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 超时检测
|
||||||
|
|
||||||
|
private readonly MainPack _timeOutPack = new MainPack { Returncode = ReturnCode.MsgTimeOut };
|
||||||
|
private void CheckCsMsgTimeOut()
|
||||||
|
{
|
||||||
|
float nowTime = GameTime.time;
|
||||||
|
for (int i = 0; i < CHECK_TIMEOUT_PERFRAME; i++)
|
||||||
|
{
|
||||||
|
m_dwLastCheckIndex = (m_dwLastCheckIndex + 1) % MAX_MSG_HANDLE;
|
||||||
|
if (m_aMsgHandles[m_dwLastCheckIndex] != null)
|
||||||
|
{
|
||||||
|
if (m_fMsgRegTime[m_dwLastCheckIndex] + m_timeout < nowTime)
|
||||||
|
{
|
||||||
|
TLogger.LogError("msg timeout, resCmdID[{0}]", m_aMsgHandles[m_dwLastCheckIndex]);
|
||||||
|
|
||||||
|
NotifyTimeout(m_aMsgHandles[m_dwLastCheckIndex]);
|
||||||
|
|
||||||
|
RmvCheckCsMsg((int)m_dwLastCheckIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RmvCheckCsMsg(int index)
|
||||||
|
{
|
||||||
|
m_aMsgHandles[index] = null;
|
||||||
|
m_fMsgRegTime[index] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RegTimeOutHandle(uint actionCode, CsMsgDelegate resHandler)
|
||||||
|
{
|
||||||
|
uint hashIndex = actionCode % MAX_MSG_HANDLE;
|
||||||
|
m_aMsgHandles[hashIndex] = resHandler;
|
||||||
|
m_fMsgRegTime[hashIndex] = GameTime.time;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void NotifyTimeout(CsMsgDelegate msgHandler)
|
||||||
|
{
|
||||||
|
msgHandler(_timeOutPack);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private void HandleCsMsgOnUpdate()
|
||||||
|
{
|
||||||
|
if (cachelistHandle.Count <= 0 || queuepPacks.Count <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (CsMsgDelegate handle in cachelistHandle.Dequeue())
|
||||||
|
{
|
||||||
|
handle(queuepPacks.Peek());
|
||||||
|
}
|
||||||
|
queuepPacks.Dequeue();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
TLogger.LogError(e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Init()
|
||||||
|
{
|
||||||
|
base.Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Active()
|
||||||
|
{
|
||||||
|
base.Active();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Release()
|
||||||
|
{
|
||||||
|
base.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsStatusCanSendMsg()
|
||||||
|
{
|
||||||
|
if (m_status == GameClientStatus.StatusEnter)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
float nowTime = GameTime.time;
|
||||||
|
if (m_lastLogDisconnectErrTime + 5 < nowTime)
|
||||||
|
{
|
||||||
|
TLogger.LogError("GameClient not connected, send msg failed");
|
||||||
|
m_lastLogDisconnectErrTime = nowTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置是否需要监控网络重连
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="needWatch"></param>
|
||||||
|
public void SetWatchReconnect(bool needWatch)
|
||||||
|
{
|
||||||
|
m_connectWatcher.Enable = needWatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Ping
|
||||||
|
/// <summary>
|
||||||
|
/// ping值
|
||||||
|
/// </summary>
|
||||||
|
public int Ping
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (IsPingValid())
|
||||||
|
{
|
||||||
|
return m_ping / 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsPingValid()
|
||||||
|
{
|
||||||
|
if (IsNetworkOkAndLogined)
|
||||||
|
{
|
||||||
|
return m_ping >= 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region GetNetworkType
|
||||||
|
public static CsNetworkType GetNetworkType()
|
||||||
|
{
|
||||||
|
CsNetworkType csNetType = CsNetworkType.CSNETWORK_UNKNOWN;
|
||||||
|
NetworkReachability reachability = Application.internetReachability;
|
||||||
|
switch (reachability)
|
||||||
|
{
|
||||||
|
case NetworkReachability.NotReachable:
|
||||||
|
break;
|
||||||
|
case NetworkReachability.ReachableViaLocalAreaNetwork:
|
||||||
|
csNetType = CsNetworkType.CSNETWORK_WIFI;
|
||||||
|
break;
|
||||||
|
case NetworkReachability.ReachableViaCarrierDataNetwork:
|
||||||
|
csNetType = CsNetworkType.CSNETWORK_3G;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return csNetType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CsNetworkType
|
||||||
|
{
|
||||||
|
CSNETWORK_UNKNOWN = 0, /*未知类型*/
|
||||||
|
CSNETWORK_WIFI = 1, /*Wifi类型*/
|
||||||
|
CSNETWORK_3G = 2, /*3G类型*/
|
||||||
|
CSNETWORK_2G = 3 /*2G类型*/
|
||||||
|
};
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
48
TEngineHotUpdate/src/TEngineCore/Net/IDataCenterModule.cs
Normal file
48
TEngineHotUpdate/src/TEngineCore/Net/IDataCenterModule.cs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
namespace TEngineCore.Net
|
||||||
|
{
|
||||||
|
public interface IDataCenterModule
|
||||||
|
{
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
void OnRoleLogout();
|
||||||
|
|
||||||
|
void OnUpdate();
|
||||||
|
|
||||||
|
void OnMainPlayerMapChange();
|
||||||
|
}
|
||||||
|
public class DataCenterModule<T> : IDataCenterModule where T : new()
|
||||||
|
{
|
||||||
|
private static T instance;
|
||||||
|
public static T Instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (null == instance)
|
||||||
|
{
|
||||||
|
instance = new T();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Init()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void OnRoleLogout()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void OnUpdate()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void OnMainPlayerMapChange()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
TEngineHotUpdate/src/TEngineCore/Net/NetEventId.cs
Normal file
9
TEngineHotUpdate/src/TEngineCore/Net/NetEventId.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace TEngineCore.Net
|
||||||
|
{
|
||||||
|
internal class NetEventId
|
||||||
|
{
|
||||||
|
public static int HeartBeat = StringId.StringToHash("NetEventId.HeartBeat");
|
||||||
|
public static int ConnectTcp = StringId.StringToHash("NetEventId.ConnectTcp");
|
||||||
|
public static int ConnectUdp = StringId.StringToHash("NetEventId.ConnectUdp");
|
||||||
|
}
|
||||||
|
}
|
52
TEngineHotUpdate/src/TEngineCore/Net/ProtoUtils.cs
Normal file
52
TEngineHotUpdate/src/TEngineCore/Net/ProtoUtils.cs
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
using System.IO;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
namespace TEngineCore.Net
|
||||||
|
{
|
||||||
|
public class ProtoUtils
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 序列化 MainPack -> byte[]
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="mainPack"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[CanBeNull]
|
||||||
|
public static byte[] Serialize<T>(T mainPack) where T : class
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var stream = new System.IO.MemoryStream())
|
||||||
|
{
|
||||||
|
ProtoBuf.Serializer.Serialize(stream, mainPack);
|
||||||
|
return stream.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
TLogger.LogError($"[Serialize] Error:{ex.Message}, {ex.Data["StackTrace"]}");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 反序列化
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="buffer"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[CanBeNull]
|
||||||
|
public static T DeSerialize<T>(byte[] buffer) where T : class
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return ProtoBuf.Serializer.Deserialize(typeof(T), new System.IO.MemoryStream(buffer)) as T;
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
TLogger.LogError(($"[DeSerialize] 错误:{ex.Message}, {ex.Data["StackTrace"]}"));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user