mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
先移除网络
先移除网络
This commit is contained in:
@@ -1,67 +1,67 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using TEngine.Runtime;
|
||||
|
||||
namespace TEngine.Editor
|
||||
{
|
||||
[CustomEditor(typeof(TEngine.Runtime.Network))]
|
||||
internal sealed class NetworkComponentInspector : TEngineInspector
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
if (!EditorApplication.isPlaying)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info);
|
||||
return;
|
||||
}
|
||||
|
||||
TEngine.Runtime.Network t = (TEngine.Runtime.Network)target;
|
||||
|
||||
if (IsPrefabInHierarchy(t.gameObject))
|
||||
{
|
||||
EditorGUILayout.LabelField("Network Channel Count", t.NetworkChannelCount.ToString());
|
||||
|
||||
INetworkChannel[] networkChannels = t.GetAllNetworkChannels();
|
||||
foreach (INetworkChannel networkChannel in networkChannels)
|
||||
{
|
||||
DrawNetworkChannel(networkChannel);
|
||||
}
|
||||
}
|
||||
|
||||
Repaint();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
}
|
||||
|
||||
private void DrawNetworkChannel(INetworkChannel networkChannel)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
{
|
||||
EditorGUILayout.LabelField(networkChannel.Name, networkChannel.Connected ? "Connected" : "Disconnected");
|
||||
EditorGUILayout.LabelField("Service Type", networkChannel.ServiceType.ToString());
|
||||
EditorGUILayout.LabelField("Address Family", networkChannel.AddressFamily.ToString());
|
||||
EditorGUILayout.LabelField("Local Address", networkChannel.Connected ? networkChannel.Socket.LocalEndPoint.ToString() : "Unavailable");
|
||||
EditorGUILayout.LabelField("Remote Address", networkChannel.Connected ? networkChannel.Socket.RemoteEndPoint.ToString() : "Unavailable");
|
||||
EditorGUILayout.LabelField("Send Packet", Utility.Text.Format("{0} / {1}", networkChannel.SendPacketCount.ToString(), networkChannel.SentPacketCount.ToString()));
|
||||
EditorGUILayout.LabelField("Receive Packet", Utility.Text.Format("{0} / {1}", networkChannel.ReceivePacketCount.ToString(), networkChannel.ReceivedPacketCount.ToString()));
|
||||
EditorGUILayout.LabelField("Miss Heart Beat Count", networkChannel.MissHeartBeatCount.ToString());
|
||||
EditorGUILayout.LabelField("Heart Beat", Utility.Text.Format("{0} / {1}", networkChannel.HeartBeatElapseSeconds.ToString("F2"), networkChannel.HeartBeatInterval.ToString("F2")));
|
||||
EditorGUI.BeginDisabledGroup(!networkChannel.Connected);
|
||||
{
|
||||
if (GUILayout.Button("Disconnect"))
|
||||
{
|
||||
networkChannel.Close();
|
||||
}
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
}
|
||||
}
|
||||
}
|
||||
// using UnityEditor;
|
||||
// using UnityEngine;
|
||||
// using TEngine.Runtime;
|
||||
//
|
||||
// namespace TEngine.Editor
|
||||
// {
|
||||
// [CustomEditor(typeof(TEngine.Runtime.Network))]
|
||||
// internal sealed class NetworkComponentInspector : TEngineInspector
|
||||
// {
|
||||
// public override void OnInspectorGUI()
|
||||
// {
|
||||
// base.OnInspectorGUI();
|
||||
//
|
||||
// if (!EditorApplication.isPlaying)
|
||||
// {
|
||||
// EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// TEngine.Runtime.Network t = (TEngine.Runtime.Network)target;
|
||||
//
|
||||
// if (IsPrefabInHierarchy(t.gameObject))
|
||||
// {
|
||||
// EditorGUILayout.LabelField("Network Channel Count", t.NetworkChannelCount.ToString());
|
||||
//
|
||||
// INetworkChannel[] networkChannels = t.GetAllNetworkChannels();
|
||||
// foreach (INetworkChannel networkChannel in networkChannels)
|
||||
// {
|
||||
// DrawNetworkChannel(networkChannel);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Repaint();
|
||||
// }
|
||||
//
|
||||
// private void OnEnable()
|
||||
// {
|
||||
// }
|
||||
//
|
||||
// private void DrawNetworkChannel(INetworkChannel networkChannel)
|
||||
// {
|
||||
// EditorGUILayout.BeginVertical("box");
|
||||
// {
|
||||
// EditorGUILayout.LabelField(networkChannel.Name, networkChannel.Connected ? "Connected" : "Disconnected");
|
||||
// EditorGUILayout.LabelField("Service Type", networkChannel.ServiceType.ToString());
|
||||
// EditorGUILayout.LabelField("Address Family", networkChannel.AddressFamily.ToString());
|
||||
// EditorGUILayout.LabelField("Local Address", networkChannel.Connected ? networkChannel.Socket.LocalEndPoint.ToString() : "Unavailable");
|
||||
// EditorGUILayout.LabelField("Remote Address", networkChannel.Connected ? networkChannel.Socket.RemoteEndPoint.ToString() : "Unavailable");
|
||||
// EditorGUILayout.LabelField("Send Packet", Utility.Text.Format("{0} / {1}", networkChannel.SendPacketCount.ToString(), networkChannel.SentPacketCount.ToString()));
|
||||
// EditorGUILayout.LabelField("Receive Packet", Utility.Text.Format("{0} / {1}", networkChannel.ReceivePacketCount.ToString(), networkChannel.ReceivedPacketCount.ToString()));
|
||||
// EditorGUILayout.LabelField("Miss Heart Beat Count", networkChannel.MissHeartBeatCount.ToString());
|
||||
// EditorGUILayout.LabelField("Heart Beat", Utility.Text.Format("{0} / {1}", networkChannel.HeartBeatElapseSeconds.ToString("F2"), networkChannel.HeartBeatInterval.ToString("F2")));
|
||||
// EditorGUI.BeginDisabledGroup(!networkChannel.Connected);
|
||||
// {
|
||||
// if (GUILayout.Button("Disconnect"))
|
||||
// {
|
||||
// networkChannel.Close();
|
||||
// }
|
||||
// }
|
||||
// EditorGUI.EndDisabledGroup();
|
||||
// }
|
||||
// EditorGUILayout.EndVertical();
|
||||
//
|
||||
// EditorGUILayout.Separator();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
@@ -1,61 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
public sealed partial class DebuggerComponent
|
||||
{
|
||||
private sealed class NetworkInformationWindow : ScrollableDebuggerWindowBase
|
||||
{
|
||||
private Network m_NetworkComponent = null;
|
||||
|
||||
public override void Initialize(params object[] args)
|
||||
{
|
||||
m_NetworkComponent = Network.Instance;
|
||||
if (m_NetworkComponent == null)
|
||||
{
|
||||
Log.Fatal("Network component is invalid.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDrawScrollableWindow()
|
||||
{
|
||||
GUILayout.Label("<b>Network Information</b>");
|
||||
GUILayout.BeginVertical("box");
|
||||
{
|
||||
DrawItem("Network Channel Count", m_NetworkComponent.NetworkChannelCount.ToString());
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
INetworkChannel[] networkChannels = m_NetworkComponent.GetAllNetworkChannels();
|
||||
for (int i = 0; i < networkChannels.Length; i++)
|
||||
{
|
||||
DrawNetworkChannel(networkChannels[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawNetworkChannel(INetworkChannel networkChannel)
|
||||
{
|
||||
GUILayout.Label(Utility.Text.Format("<b>Network Channel: {0} ({1})</b>", networkChannel.Name, networkChannel.Connected ? "Connected" : "Disconnected"));
|
||||
GUILayout.BeginVertical("box");
|
||||
{
|
||||
DrawItem("Service Type", networkChannel.ServiceType.ToString());
|
||||
DrawItem("Address Family", networkChannel.AddressFamily.ToString());
|
||||
DrawItem("Local Address", networkChannel.Connected ? networkChannel.Socket.LocalEndPoint.ToString() : "Unavailable");
|
||||
DrawItem("Remote Address", networkChannel.Connected ? networkChannel.Socket.RemoteEndPoint.ToString() : "Unavailable");
|
||||
DrawItem("Send Packet", Utility.Text.Format("{0} / {1}", networkChannel.SendPacketCount.ToString(), networkChannel.SentPacketCount.ToString()));
|
||||
DrawItem("Receive Packet", Utility.Text.Format("{0} / {1}", networkChannel.ReceivePacketCount.ToString(), networkChannel.ReceivedPacketCount.ToString()));
|
||||
DrawItem("Miss Heart Beat Count", networkChannel.MissHeartBeatCount.ToString());
|
||||
DrawItem("Heart Beat", Utility.Text.Format("{0} / {1}", networkChannel.HeartBeatElapseSeconds.ToString("F2"), networkChannel.HeartBeatInterval.ToString("F2")));
|
||||
if (networkChannel.Connected)
|
||||
{
|
||||
if (GUILayout.Button("Disconnect", GUILayout.Height(30f)))
|
||||
{
|
||||
networkChannel.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9234c66fc6c4421ad762cf70fe9e0a0
|
||||
timeCreated: 1661828316
|
@@ -189,7 +189,7 @@ namespace TEngine.Runtime
|
||||
private RuntimeMemoryInformationWindow<ScriptableObject> m_RuntimeMemoryScriptableObjectInformationWindow = new RuntimeMemoryInformationWindow<ScriptableObject>();
|
||||
|
||||
private MemoryPoolInformationWindow m_MemoryPoolInformationWindow = new MemoryPoolInformationWindow();
|
||||
private NetworkInformationWindow m_NetworkInformationWindow = new NetworkInformationWindow();
|
||||
// private NetworkInformationWindow m_NetworkInformationWindow = new NetworkInformationWindow();
|
||||
|
||||
private SettingsWindow m_SettingsWindow = new SettingsWindow();
|
||||
#endregion
|
||||
@@ -229,7 +229,7 @@ namespace TEngine.Runtime
|
||||
RegisterDebuggerWindow("Profiler/Memory/ScriptableObject", m_RuntimeMemoryScriptableObjectInformationWindow);
|
||||
|
||||
RegisterDebuggerWindow("Profiler/Memory Pool", m_MemoryPoolInformationWindow);
|
||||
RegisterDebuggerWindow("Profiler/Network", m_NetworkInformationWindow);
|
||||
// RegisterDebuggerWindow("Profiler/Network", m_NetworkInformationWindow);
|
||||
|
||||
RegisterDebuggerWindow("Other/Settings", m_SettingsWindow);
|
||||
|
||||
|
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69740261aa305b94aa6a2a717d82d8e4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,23 +0,0 @@
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络地址类型。
|
||||
/// </summary>
|
||||
public enum AddressFamily : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// 未知。
|
||||
/// </summary>
|
||||
Unknown = 0,
|
||||
|
||||
/// <summary>
|
||||
/// IP 版本 4。
|
||||
/// </summary>
|
||||
IPv4,
|
||||
|
||||
/// <summary>
|
||||
/// IP 版本 6。
|
||||
/// </summary>
|
||||
IPv6
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f0c907c7aeb4bd2a19ff78ad8e8b668
|
||||
timeCreated: 1661772419
|
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c4f37bbaa3a4ae45a5aa851ec78c3d0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b7b82bd3d86d874c978bebc6147b442
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,120 +0,0 @@
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络连接关闭事件。
|
||||
/// </summary>
|
||||
public sealed class NetworkClosedEventArgs : GameEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络连接关闭事件编号。
|
||||
/// </summary>
|
||||
public static readonly int EventId = typeof(NetworkClosedEventArgs).GetHashCode();
|
||||
|
||||
/// <summary>
|
||||
/// 初始化网络连接关闭事件的新实例。
|
||||
/// </summary>
|
||||
public NetworkClosedEventArgs()
|
||||
{
|
||||
NetworkChannel = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络连接关闭事件编号。
|
||||
/// </summary>
|
||||
public override int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return EventId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络频道。
|
||||
/// </summary>
|
||||
public INetworkChannel NetworkChannel
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建网络连接关闭事件。
|
||||
/// </summary>
|
||||
/// <param name="networkChannel">网络频道。</param>
|
||||
/// <returns>创建的网络连接关闭事件。</returns>
|
||||
public static NetworkClosedEventArgs Create(INetworkChannel networkChannel)
|
||||
{
|
||||
NetworkClosedEventArgs networkClosedEventArgs = MemoryPool.Acquire<NetworkClosedEventArgs>();
|
||||
networkClosedEventArgs.NetworkChannel = networkChannel;
|
||||
return networkClosedEventArgs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理网络连接关闭事件。
|
||||
/// </summary>
|
||||
public override void Clear()
|
||||
{
|
||||
NetworkChannel = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 网络连接关闭事件。
|
||||
/// </summary>
|
||||
public sealed class NetworkClosedEvent : GameEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络连接关闭事件编号。
|
||||
/// </summary>
|
||||
public static readonly int EventId = typeof(NetworkClosedEvent).GetHashCode();
|
||||
|
||||
/// <summary>
|
||||
/// 初始化网络连接关闭事件的新实例。
|
||||
/// </summary>
|
||||
public NetworkClosedEvent()
|
||||
{
|
||||
NetworkChannel = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络连接关闭事件编号。
|
||||
/// </summary>
|
||||
public override int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return EventId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络频道。
|
||||
/// </summary>
|
||||
public INetworkChannel NetworkChannel
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建网络连接关闭事件。
|
||||
/// </summary>
|
||||
/// <param name="e">内部事件。</param>
|
||||
/// <returns>创建的网络连接关闭事件。</returns>
|
||||
public static NetworkClosedEvent Create(NetworkClosedEventArgs e)
|
||||
{
|
||||
NetworkClosedEvent networkClosedEventArgs = MemoryPool.Acquire<NetworkClosedEvent>();
|
||||
networkClosedEventArgs.NetworkChannel = e.NetworkChannel;
|
||||
return networkClosedEventArgs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理网络连接关闭事件。
|
||||
/// </summary>
|
||||
public override void Clear()
|
||||
{
|
||||
NetworkChannel = null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6218d5320c6b4a328df908e68d135177
|
||||
timeCreated: 1661772187
|
@@ -1,142 +0,0 @@
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络连接成功事件。
|
||||
/// </summary>
|
||||
public sealed class NetworkConnectedEventArgs : GameEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络连接成功事件编号。
|
||||
/// </summary>
|
||||
public static readonly int EventId = typeof(NetworkConnectedEventArgs).GetHashCode();
|
||||
|
||||
/// <summary>
|
||||
/// 初始化网络连接成功事件的新实例。
|
||||
/// </summary>
|
||||
public NetworkConnectedEventArgs()
|
||||
{
|
||||
NetworkChannel = null;
|
||||
UserData = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络连接成功事件编号。
|
||||
/// </summary>
|
||||
public override int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return EventId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络频道。
|
||||
/// </summary>
|
||||
public INetworkChannel NetworkChannel
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取用户自定义数据。
|
||||
/// </summary>
|
||||
public object UserData
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建网络连接成功事件。
|
||||
/// </summary>
|
||||
/// <param name="networkChannel">网络频道。</param>
|
||||
/// <param name="userData">用户自定义数据。</param>
|
||||
/// <returns>创建的网络连接成功事件。</returns>
|
||||
public static NetworkConnectedEventArgs Create(INetworkChannel networkChannel)
|
||||
{
|
||||
NetworkConnectedEventArgs networkConnectedEventArgs = MemoryPool.Acquire<NetworkConnectedEventArgs>();
|
||||
networkConnectedEventArgs.NetworkChannel = networkChannel;
|
||||
networkConnectedEventArgs.UserData = null;
|
||||
return networkConnectedEventArgs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理网络连接成功事件。
|
||||
/// </summary>
|
||||
public override void Clear()
|
||||
{
|
||||
NetworkChannel = null;
|
||||
UserData = null;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class NetworkConnectedEvent : GameEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络连接成功事件编号。
|
||||
/// </summary>
|
||||
public static readonly int EventId = typeof(NetworkConnectedEvent).GetHashCode();
|
||||
|
||||
/// <summary>
|
||||
/// 初始化网络连接成功事件的新实例。
|
||||
/// </summary>
|
||||
public NetworkConnectedEvent()
|
||||
{
|
||||
NetworkChannel = null;
|
||||
UserData = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络连接成功事件编号。
|
||||
/// </summary>
|
||||
public override int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return EventId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络频道。
|
||||
/// </summary>
|
||||
public INetworkChannel NetworkChannel
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取用户自定义数据。
|
||||
/// </summary>
|
||||
public object UserData
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建网络连接成功事件。
|
||||
/// </summary>
|
||||
/// <param name="e">内部事件。</param>
|
||||
/// <returns>创建的网络连接成功事件。</returns>
|
||||
public static NetworkConnectedEvent Create(NetworkConnectedEventArgs e)
|
||||
{
|
||||
NetworkConnectedEvent networkConnectedEventArgs = MemoryPool.Acquire<NetworkConnectedEvent>();
|
||||
networkConnectedEventArgs.NetworkChannel = e.NetworkChannel;
|
||||
networkConnectedEventArgs.UserData = e.UserData;
|
||||
return networkConnectedEventArgs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理网络连接成功事件。
|
||||
/// </summary>
|
||||
public override void Clear()
|
||||
{
|
||||
NetworkChannel = null;
|
||||
UserData = null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 64fffbe4a72442f0b3bbd81f78509b13
|
||||
timeCreated: 1661772223
|
@@ -1,145 +0,0 @@
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户自定义网络错误事件。
|
||||
/// </summary>
|
||||
public sealed class NetworkCustomErrorEventArgs : GameEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户自定义网络错误事件编号。
|
||||
/// </summary>
|
||||
public static readonly int EventId = typeof(NetworkCustomErrorEventArgs).GetHashCode();
|
||||
|
||||
/// <summary>
|
||||
/// 初始化用户自定义网络错误事件的新实例。
|
||||
/// </summary>
|
||||
public NetworkCustomErrorEventArgs()
|
||||
{
|
||||
NetworkChannel = null;
|
||||
CustomErrorData = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取用户自定义网络错误事件编号。
|
||||
/// </summary>
|
||||
public override int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return EventId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络频道。
|
||||
/// </summary>
|
||||
public INetworkChannel NetworkChannel
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取用户自定义错误数据。
|
||||
/// </summary>
|
||||
public object CustomErrorData
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建用户自定义网络错误事件。
|
||||
/// </summary>
|
||||
/// <param name="networkChannel">网络频道。</param>
|
||||
/// <param name="customErrorData">用户自定义错误数据。</param>
|
||||
/// <returns>创建的用户自定义网络错误事件。</returns>
|
||||
public static NetworkCustomErrorEventArgs Create(INetworkChannel networkChannel, object customErrorData)
|
||||
{
|
||||
NetworkCustomErrorEventArgs networkCustomErrorEventArgs = MemoryPool.Acquire<NetworkCustomErrorEventArgs>();
|
||||
networkCustomErrorEventArgs.NetworkChannel = networkChannel;
|
||||
networkCustomErrorEventArgs.CustomErrorData = customErrorData;
|
||||
return networkCustomErrorEventArgs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理用户自定义网络错误事件。
|
||||
/// </summary>
|
||||
public override void Clear()
|
||||
{
|
||||
NetworkChannel = null;
|
||||
CustomErrorData = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用户自定义网络错误事件。
|
||||
/// </summary>
|
||||
public sealed class NetworkCustomErrorEvent : GameEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户自定义网络错误事件编号。
|
||||
/// </summary>
|
||||
public static readonly int EventId = typeof(NetworkCustomErrorEvent).GetHashCode();
|
||||
|
||||
/// <summary>
|
||||
/// 初始化用户自定义网络错误事件的新实例。
|
||||
/// </summary>
|
||||
public NetworkCustomErrorEvent()
|
||||
{
|
||||
NetworkChannel = null;
|
||||
CustomErrorData = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取用户自定义网络错误事件编号。
|
||||
/// </summary>
|
||||
public override int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return EventId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络频道。
|
||||
/// </summary>
|
||||
public INetworkChannel NetworkChannel
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取用户自定义错误数据。
|
||||
/// </summary>
|
||||
public object CustomErrorData
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建用户自定义网络错误事件。
|
||||
/// </summary>
|
||||
/// <param name="e">内部事件。</param>
|
||||
/// <returns>创建的用户自定义网络错误事件。</returns>
|
||||
public static NetworkCustomErrorEvent Create(NetworkCustomErrorEventArgs e)
|
||||
{
|
||||
NetworkCustomErrorEvent networkCustomErrorEventArgs = MemoryPool.Acquire<NetworkCustomErrorEvent>();
|
||||
networkCustomErrorEventArgs.NetworkChannel = e.NetworkChannel;
|
||||
networkCustomErrorEventArgs.CustomErrorData = e.CustomErrorData;
|
||||
return networkCustomErrorEventArgs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理用户自定义网络错误事件。
|
||||
/// </summary>
|
||||
public override void Clear()
|
||||
{
|
||||
NetworkChannel = null;
|
||||
CustomErrorData = null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6947eca0814140a6a7fc564274cdb804
|
||||
timeCreated: 1661772258
|
@@ -1,195 +0,0 @@
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络错误事件。
|
||||
/// </summary>
|
||||
public sealed class NetworkErrorEventArgs : GameEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络错误事件编号。
|
||||
/// </summary>
|
||||
public static readonly int EventId = typeof(NetworkErrorEventArgs).GetHashCode();
|
||||
|
||||
/// <summary>
|
||||
/// 初始化网络错误事件的新实例。
|
||||
/// </summary>
|
||||
public NetworkErrorEventArgs()
|
||||
{
|
||||
NetworkChannel = null;
|
||||
ErrorCode = NetworkErrorCode.Unknown;
|
||||
SocketErrorCode = SocketError.Success;
|
||||
ErrorMessage = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络错误事件编号。
|
||||
/// </summary>
|
||||
public override int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return EventId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络频道。
|
||||
/// </summary>
|
||||
public INetworkChannel NetworkChannel
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取错误码。
|
||||
/// </summary>
|
||||
public NetworkErrorCode ErrorCode
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取 Socket 错误码。
|
||||
/// </summary>
|
||||
public SocketError SocketErrorCode
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取错误信息。
|
||||
/// </summary>
|
||||
public string ErrorMessage
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建网络错误事件。
|
||||
/// </summary>
|
||||
/// <param name="networkChannel">网络频道。</param>
|
||||
/// <param name="errorCode">错误码。</param>
|
||||
/// <param name="socketErrorCode">Socket 错误码。</param>
|
||||
/// <param name="errorMessage">错误信息。</param>
|
||||
/// <returns>创建的网络错误事件。</returns>
|
||||
public static NetworkErrorEventArgs Create(INetworkChannel networkChannel, NetworkErrorCode errorCode, SocketError socketErrorCode, string errorMessage)
|
||||
{
|
||||
NetworkErrorEventArgs networkErrorEventArgs = MemoryPool.Acquire<NetworkErrorEventArgs>();
|
||||
networkErrorEventArgs.NetworkChannel = networkChannel;
|
||||
networkErrorEventArgs.ErrorCode = errorCode;
|
||||
networkErrorEventArgs.SocketErrorCode = socketErrorCode;
|
||||
networkErrorEventArgs.ErrorMessage = errorMessage;
|
||||
return networkErrorEventArgs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理网络错误事件。
|
||||
/// </summary>
|
||||
public override void Clear()
|
||||
{
|
||||
NetworkChannel = null;
|
||||
ErrorCode = NetworkErrorCode.Unknown;
|
||||
SocketErrorCode = SocketError.Success;
|
||||
ErrorMessage = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 网络错误事件。
|
||||
/// </summary>
|
||||
public sealed class NetworkErrorEvent : GameEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络错误事件编号。
|
||||
/// </summary>
|
||||
public static readonly int EventId = typeof(NetworkErrorEvent).GetHashCode();
|
||||
|
||||
/// <summary>
|
||||
/// 初始化网络错误事件的新实例。
|
||||
/// </summary>
|
||||
public NetworkErrorEvent()
|
||||
{
|
||||
NetworkChannel = null;
|
||||
ErrorCode = NetworkErrorCode.Unknown;
|
||||
ErrorMessage = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络错误事件编号。
|
||||
/// </summary>
|
||||
public override int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return EventId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络频道。
|
||||
/// </summary>
|
||||
public INetworkChannel NetworkChannel
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取错误码。
|
||||
/// </summary>
|
||||
public NetworkErrorCode ErrorCode
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取 Socket 错误码。
|
||||
/// </summary>
|
||||
public SocketError SocketErrorCode
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取错误信息。
|
||||
/// </summary>
|
||||
public string ErrorMessage
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建网络错误事件。
|
||||
/// </summary>
|
||||
/// <param name="e">内部事件。</param>
|
||||
/// <returns>创建的网络错误事件。</returns>
|
||||
public static NetworkErrorEvent Create(NetworkErrorEventArgs e)
|
||||
{
|
||||
NetworkErrorEvent networkErrorEventArgs = MemoryPool.Acquire<NetworkErrorEvent>();
|
||||
networkErrorEventArgs.NetworkChannel = e.NetworkChannel;
|
||||
networkErrorEventArgs.ErrorCode = e.ErrorCode;
|
||||
networkErrorEventArgs.SocketErrorCode = e.SocketErrorCode;
|
||||
networkErrorEventArgs.ErrorMessage = e.ErrorMessage;
|
||||
return networkErrorEventArgs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理网络错误事件。
|
||||
/// </summary>
|
||||
public override void Clear()
|
||||
{
|
||||
NetworkChannel = null;
|
||||
ErrorCode = NetworkErrorCode.Unknown;
|
||||
ErrorMessage = null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7f64b74fa985459b88f908ff182e8672
|
||||
timeCreated: 1661772293
|
@@ -1,145 +0,0 @@
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络心跳包丢失事件。
|
||||
/// </summary>
|
||||
public sealed class NetworkMissHeartBeatEventArgs : GameEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络心跳包丢失事件编号。
|
||||
/// </summary>
|
||||
public static readonly int EventId = typeof(NetworkMissHeartBeatEventArgs).GetHashCode();
|
||||
|
||||
/// <summary>
|
||||
/// 初始化网络心跳包丢失事件的新实例。
|
||||
/// </summary>
|
||||
public NetworkMissHeartBeatEventArgs()
|
||||
{
|
||||
NetworkChannel = null;
|
||||
MissCount = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络心跳包丢失事件编号。
|
||||
/// </summary>
|
||||
public override int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return EventId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络频道。
|
||||
/// </summary>
|
||||
public INetworkChannel NetworkChannel
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取心跳包已丢失次数。
|
||||
/// </summary>
|
||||
public int MissCount
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建网络心跳包丢失事件。
|
||||
/// </summary>
|
||||
/// <param name="networkChannel">网络频道。</param>
|
||||
/// <param name="missCount">心跳包已丢失次数。</param>
|
||||
/// <returns>创建的网络心跳包丢失事件。</returns>
|
||||
public static NetworkMissHeartBeatEventArgs Create(INetworkChannel networkChannel, int missCount)
|
||||
{
|
||||
NetworkMissHeartBeatEventArgs networkMissHeartBeatEventArgs = MemoryPool.Acquire<NetworkMissHeartBeatEventArgs>();
|
||||
networkMissHeartBeatEventArgs.NetworkChannel = networkChannel;
|
||||
networkMissHeartBeatEventArgs.MissCount = missCount;
|
||||
return networkMissHeartBeatEventArgs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理网络心跳包丢失事件。
|
||||
/// </summary>
|
||||
public override void Clear()
|
||||
{
|
||||
NetworkChannel = null;
|
||||
MissCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 网络心跳包丢失事件。
|
||||
/// </summary>
|
||||
public sealed class NetworkMissHeartBeatEvent : GameEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络心跳包丢失事件编号。
|
||||
/// </summary>
|
||||
public static readonly int EventId = typeof(NetworkMissHeartBeatEvent).GetHashCode();
|
||||
|
||||
/// <summary>
|
||||
/// 初始化网络心跳包丢失事件的新实例。
|
||||
/// </summary>
|
||||
public NetworkMissHeartBeatEvent()
|
||||
{
|
||||
NetworkChannel = null;
|
||||
MissCount = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络心跳包丢失事件编号。
|
||||
/// </summary>
|
||||
public override int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return EventId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络频道。
|
||||
/// </summary>
|
||||
public INetworkChannel NetworkChannel
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取心跳包已丢失次数。
|
||||
/// </summary>
|
||||
public int MissCount
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建网络心跳包丢失事件。
|
||||
/// </summary>
|
||||
/// <param name="e">内部事件。</param>
|
||||
/// <returns>创建的网络心跳包丢失事件。</returns>
|
||||
public static NetworkMissHeartBeatEvent Create(NetworkMissHeartBeatEventArgs e)
|
||||
{
|
||||
NetworkMissHeartBeatEvent networkMissHeartBeatEventArgs = MemoryPool.Acquire<NetworkMissHeartBeatEvent>();
|
||||
networkMissHeartBeatEventArgs.NetworkChannel = e.NetworkChannel;
|
||||
networkMissHeartBeatEventArgs.MissCount = e.MissCount;
|
||||
return networkMissHeartBeatEventArgs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理网络心跳包丢失事件。
|
||||
/// </summary>
|
||||
public override void Clear()
|
||||
{
|
||||
NetworkChannel = null;
|
||||
MissCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c2dc35d1fb8047e3b86f4af42124aa06
|
||||
timeCreated: 1661772338
|
@@ -1,130 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 事件管理器。
|
||||
/// </summary>
|
||||
internal sealed class EventManager: IEventManager
|
||||
{
|
||||
private readonly EventPool<GameEventArgs> m_EventPool;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化事件管理器的新实例。
|
||||
/// </summary>
|
||||
public EventManager()
|
||||
{
|
||||
m_EventPool = new EventPool<GameEventArgs>(EventPoolMode.AllowNoHandler | EventPoolMode.AllowMultiHandler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取事件处理函数的数量。
|
||||
/// </summary>
|
||||
public int EventHandlerCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_EventPool.EventHandlerCount;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取事件数量。
|
||||
/// </summary>
|
||||
public int EventCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_EventPool.EventCount;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 事件管理器轮询。
|
||||
/// </summary>
|
||||
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
|
||||
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
|
||||
public void Update(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
m_EventPool.Update(elapseSeconds, realElapseSeconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭并清理事件管理器。
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
m_EventPool.Shutdown();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取事件处理函数的数量。
|
||||
/// </summary>
|
||||
/// <param name="id">事件类型编号。</param>
|
||||
/// <returns>事件处理函数的数量。</returns>
|
||||
public int Count(int id)
|
||||
{
|
||||
return m_EventPool.Count(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在事件处理函数。
|
||||
/// </summary>
|
||||
/// <param name="id">事件类型编号。</param>
|
||||
/// <param name="handler">要检查的事件处理函数。</param>
|
||||
/// <returns>是否存在事件处理函数。</returns>
|
||||
public bool Check(int id, EventHandler<GameEventArgs> handler)
|
||||
{
|
||||
return m_EventPool.Check(id, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 订阅事件处理函数。
|
||||
/// </summary>
|
||||
/// <param name="id">事件类型编号。</param>
|
||||
/// <param name="handler">要订阅的事件处理函数。</param>
|
||||
public void Subscribe(int id, EventHandler<GameEventArgs> handler)
|
||||
{
|
||||
m_EventPool.Subscribe(id, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取消订阅事件处理函数。
|
||||
/// </summary>
|
||||
/// <param name="id">事件类型编号。</param>
|
||||
/// <param name="handler">要取消订阅的事件处理函数。</param>
|
||||
public void Unsubscribe(int id, EventHandler<GameEventArgs> handler)
|
||||
{
|
||||
m_EventPool.Unsubscribe(id, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置默认事件处理函数。
|
||||
/// </summary>
|
||||
/// <param name="handler">要设置的默认事件处理函数。</param>
|
||||
public void SetDefaultHandler(EventHandler<GameEventArgs> handler)
|
||||
{
|
||||
m_EventPool.SetDefaultHandler(handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 抛出事件,这个操作是线程安全的,即使不在主线程中抛出,也可保证在主线程中回调事件处理函数,但事件会在抛出后的下一帧分发。
|
||||
/// </summary>
|
||||
/// <param name="sender">事件源。</param>
|
||||
/// <param name="e">事件参数。</param>
|
||||
public void Fire(object sender, GameEventArgs e)
|
||||
{
|
||||
m_EventPool.Fire(sender, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 抛出事件立即模式,这个操作不是线程安全的,事件会立刻分发。
|
||||
/// </summary>
|
||||
/// <param name="sender">事件源。</param>
|
||||
/// <param name="e">事件参数。</param>
|
||||
public void FireNow(object sender, GameEventArgs e)
|
||||
{
|
||||
m_EventPool.FireNow(sender, e);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5caf443f519944048edbf1bea889f6d2
|
||||
timeCreated: 1661775799
|
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b813480944c71f47a87c3facb84bce2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,31 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 事件基类。
|
||||
/// </summary>
|
||||
public abstract class BaseEventArgs : EventArgs, IMemory
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public BaseEventArgs()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取类型编号。
|
||||
/// </summary>
|
||||
public abstract int Id
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理引用。
|
||||
/// </summary>
|
||||
public abstract void Clear();
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 996eb2d764ee87b45a2d2aab7b88e148
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,50 +0,0 @@
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
internal sealed partial class EventPool<T> where T : BaseEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 事件结点。
|
||||
/// </summary>
|
||||
private sealed class Event : IMemory
|
||||
{
|
||||
private object m_Sender;
|
||||
private T m_EventArgs;
|
||||
|
||||
public Event()
|
||||
{
|
||||
m_Sender = null;
|
||||
m_EventArgs = null;
|
||||
}
|
||||
|
||||
public object Sender
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Sender;
|
||||
}
|
||||
}
|
||||
|
||||
public T EventArgs
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_EventArgs;
|
||||
}
|
||||
}
|
||||
|
||||
public static Event Create(object sender, T e)
|
||||
{
|
||||
Event eventNode = MemoryPool.Acquire<Event>();
|
||||
eventNode.m_Sender = sender;
|
||||
eventNode.m_EventArgs = e;
|
||||
return eventNode;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
m_Sender = null;
|
||||
m_EventArgs = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 342958da5a55f9647a13c573988bdec5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,278 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 事件池。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">事件类型。</typeparam>
|
||||
internal sealed partial class EventPool<T> where T : BaseEventArgs
|
||||
{
|
||||
private readonly MultiDictionary<int, EventHandler<T>> m_EventHandlers;
|
||||
private readonly Queue<Event> m_Events;
|
||||
private readonly Dictionary<object, LinkedListNode<EventHandler<T>>> m_CachedNodes;
|
||||
private readonly Dictionary<object, LinkedListNode<EventHandler<T>>> m_TempNodes;
|
||||
private readonly EventPoolMode m_EventPoolMode;
|
||||
private EventHandler<T> m_DefaultHandler;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化事件池的新实例。
|
||||
/// </summary>
|
||||
/// <param name="mode">事件池模式。</param>
|
||||
public EventPool(EventPoolMode mode)
|
||||
{
|
||||
m_EventHandlers = new MultiDictionary<int, EventHandler<T>>();
|
||||
m_Events = new Queue<Event>();
|
||||
m_CachedNodes = new Dictionary<object, LinkedListNode<EventHandler<T>>>();
|
||||
m_TempNodes = new Dictionary<object, LinkedListNode<EventHandler<T>>>();
|
||||
m_EventPoolMode = mode;
|
||||
m_DefaultHandler = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取事件处理函数的数量。
|
||||
/// </summary>
|
||||
public int EventHandlerCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_EventHandlers.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取事件数量。
|
||||
/// </summary>
|
||||
public int EventCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Events.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 事件池轮询。
|
||||
/// </summary>
|
||||
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
|
||||
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
|
||||
public void Update(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
lock (m_Events)
|
||||
{
|
||||
while (m_Events.Count > 0)
|
||||
{
|
||||
Event eventNode = m_Events.Dequeue();
|
||||
HandleEvent(eventNode.Sender, eventNode.EventArgs);
|
||||
MemoryPool.Release(eventNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭并清理事件池。
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
Clear();
|
||||
m_EventHandlers.Clear();
|
||||
m_CachedNodes.Clear();
|
||||
m_TempNodes.Clear();
|
||||
m_DefaultHandler = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理事件。
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
lock (m_Events)
|
||||
{
|
||||
m_Events.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取事件处理函数的数量。
|
||||
/// </summary>
|
||||
/// <param name="id">事件类型编号。</param>
|
||||
/// <returns>事件处理函数的数量。</returns>
|
||||
public int Count(int id)
|
||||
{
|
||||
LinkedListRange<EventHandler<T>> range = default(LinkedListRange<EventHandler<T>>);
|
||||
if (m_EventHandlers.TryGetValue(id, out range))
|
||||
{
|
||||
return range.Count;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在事件处理函数。
|
||||
/// </summary>
|
||||
/// <param name="id">事件类型编号。</param>
|
||||
/// <param name="handler">要检查的事件处理函数。</param>
|
||||
/// <returns>是否存在事件处理函数。</returns>
|
||||
public bool Check(int id, EventHandler<T> handler)
|
||||
{
|
||||
if (handler == null)
|
||||
{
|
||||
throw new Exception("Event handler is invalid.");
|
||||
}
|
||||
|
||||
return m_EventHandlers.Contains(id, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 订阅事件处理函数。
|
||||
/// </summary>
|
||||
/// <param name="id">事件类型编号。</param>
|
||||
/// <param name="handler">要订阅的事件处理函数。</param>
|
||||
public void Subscribe(int id, EventHandler<T> handler)
|
||||
{
|
||||
if (handler == null)
|
||||
{
|
||||
throw new Exception("Event handler is invalid.");
|
||||
}
|
||||
|
||||
if (!m_EventHandlers.Contains(id))
|
||||
{
|
||||
m_EventHandlers.Add(id, handler);
|
||||
}
|
||||
else if ((m_EventPoolMode & EventPoolMode.AllowMultiHandler) != EventPoolMode.AllowMultiHandler)
|
||||
{
|
||||
throw new Exception(Utility.Text.Format("Event '{0}' not allow multi handler.", id));
|
||||
}
|
||||
else if ((m_EventPoolMode & EventPoolMode.AllowDuplicateHandler) != EventPoolMode.AllowDuplicateHandler && Check(id, handler))
|
||||
{
|
||||
throw new Exception(Utility.Text.Format("Event '{0}' not allow duplicate handler.", id));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_EventHandlers.Add(id, handler);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取消订阅事件处理函数。
|
||||
/// </summary>
|
||||
/// <param name="id">事件类型编号。</param>
|
||||
/// <param name="handler">要取消订阅的事件处理函数。</param>
|
||||
public void Unsubscribe(int id, EventHandler<T> handler)
|
||||
{
|
||||
if (handler == null)
|
||||
{
|
||||
throw new Exception("Event handler is invalid.");
|
||||
}
|
||||
|
||||
if (m_CachedNodes.Count > 0)
|
||||
{
|
||||
foreach (KeyValuePair<object, LinkedListNode<EventHandler<T>>> cachedNode in m_CachedNodes)
|
||||
{
|
||||
if (cachedNode.Value != null && cachedNode.Value.Value == handler)
|
||||
{
|
||||
m_TempNodes.Add(cachedNode.Key, cachedNode.Value.Next);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_TempNodes.Count > 0)
|
||||
{
|
||||
foreach (KeyValuePair<object, LinkedListNode<EventHandler<T>>> cachedNode in m_TempNodes)
|
||||
{
|
||||
m_CachedNodes[cachedNode.Key] = cachedNode.Value;
|
||||
}
|
||||
|
||||
m_TempNodes.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_EventHandlers.Count >=0 && !m_EventHandlers.Remove(id, handler))
|
||||
{
|
||||
throw new Exception(Utility.Text.Format("Event '{0}' not exists specified handler.", id));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置默认事件处理函数。
|
||||
/// </summary>
|
||||
/// <param name="handler">要设置的默认事件处理函数。</param>
|
||||
public void SetDefaultHandler(EventHandler<T> handler)
|
||||
{
|
||||
m_DefaultHandler = handler;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 抛出事件,这个操作是线程安全的,即使不在主线程中抛出,也可保证在主线程中回调事件处理函数,但事件会在抛出后的下一帧分发。
|
||||
/// </summary>
|
||||
/// <param name="sender">事件源。</param>
|
||||
/// <param name="e">事件参数。</param>
|
||||
public void Fire(object sender, T e)
|
||||
{
|
||||
if (e == null)
|
||||
{
|
||||
throw new Exception("Event is invalid.");
|
||||
}
|
||||
|
||||
Event eventNode = Event.Create(sender, e);
|
||||
lock (m_Events)
|
||||
{
|
||||
m_Events.Enqueue(eventNode);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 抛出事件立即模式,这个操作不是线程安全的,事件会立刻分发。
|
||||
/// </summary>
|
||||
/// <param name="sender">事件源。</param>
|
||||
/// <param name="e">事件参数。</param>
|
||||
public void FireNow(object sender, T e)
|
||||
{
|
||||
if (e == null)
|
||||
{
|
||||
throw new Exception("Event is invalid.");
|
||||
}
|
||||
|
||||
HandleEvent(sender, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理事件结点。
|
||||
/// </summary>
|
||||
/// <param name="sender">事件源。</param>
|
||||
/// <param name="e">事件参数。</param>
|
||||
private void HandleEvent(object sender, T e)
|
||||
{
|
||||
bool noHandlerException = false;
|
||||
LinkedListRange<EventHandler<T>> range = default(LinkedListRange<EventHandler<T>>);
|
||||
if (m_EventHandlers.TryGetValue(e.Id, out range))
|
||||
{
|
||||
LinkedListNode<EventHandler<T>> current = range.First;
|
||||
while (current != null && current != range.Terminal)
|
||||
{
|
||||
m_CachedNodes[e] = current.Next != range.Terminal ? current.Next : null;
|
||||
current.Value(sender, e);
|
||||
current = m_CachedNodes[e];
|
||||
}
|
||||
|
||||
m_CachedNodes.Remove(e);
|
||||
}
|
||||
else if (m_DefaultHandler != null)
|
||||
{
|
||||
m_DefaultHandler(sender, e);
|
||||
}
|
||||
else if ((m_EventPoolMode & EventPoolMode.AllowNoHandler) == 0)
|
||||
{
|
||||
noHandlerException = true;
|
||||
}
|
||||
|
||||
MemoryPool.Release(e);
|
||||
|
||||
if (noHandlerException)
|
||||
{
|
||||
throw new Exception(Utility.Text.Format("Event '{0}' not allow no handler.", e.Id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5b63a6b52c0c9e42bb270c6756aac26
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,31 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 事件池模式。
|
||||
/// </summary>
|
||||
[Flags]
|
||||
internal enum EventPoolMode : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// 默认事件池模式,即必须存在有且只有一个事件处理函数。
|
||||
/// </summary>
|
||||
Default = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 允许不存在事件处理函数。
|
||||
/// </summary>
|
||||
AllowNoHandler = 1,
|
||||
|
||||
/// <summary>
|
||||
/// 允许存在多个事件处理函数。
|
||||
/// </summary>
|
||||
AllowMultiHandler = 2,
|
||||
|
||||
/// <summary>
|
||||
/// 允许存在重复的事件处理函数。
|
||||
/// </summary>
|
||||
AllowDuplicateHandler = 4
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c15df25d44d958f47a48a7ae0f26018c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,9 +0,0 @@
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏逻辑事件基类。
|
||||
/// </summary>
|
||||
public abstract class GameEventArgs : BaseEventArgs
|
||||
{
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: af3ac5182b9c4df9b51b8720629f19a8
|
||||
timeCreated: 1661775780
|
@@ -1,87 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 事件管理器接口。
|
||||
/// </summary>
|
||||
public interface IEventManager
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取事件处理函数的数量。
|
||||
/// </summary>
|
||||
int EventHandlerCount
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取事件数量。
|
||||
/// </summary>
|
||||
int EventCount
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取事件处理函数的数量。
|
||||
/// </summary>
|
||||
/// <param name="id">事件类型编号。</param>
|
||||
/// <returns>事件处理函数的数量。</returns>
|
||||
int Count(int id);
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在事件处理函数。
|
||||
/// </summary>
|
||||
/// <param name="id">事件类型编号。</param>
|
||||
/// <param name="handler">要检查的事件处理函数。</param>
|
||||
/// <returns>是否存在事件处理函数。</returns>
|
||||
bool Check(int id, EventHandler<GameEventArgs> handler);
|
||||
|
||||
/// <summary>
|
||||
/// 订阅事件处理函数。
|
||||
/// </summary>
|
||||
/// <param name="id">事件类型编号。</param>
|
||||
/// <param name="handler">要订阅的事件处理函数。</param>
|
||||
void Subscribe(int id, EventHandler<GameEventArgs> handler);
|
||||
|
||||
/// <summary>
|
||||
/// 取消订阅事件处理函数。
|
||||
/// </summary>
|
||||
/// <param name="id">事件类型编号。</param>
|
||||
/// <param name="handler">要取消订阅的事件处理函数。</param>
|
||||
void Unsubscribe(int id, EventHandler<GameEventArgs> handler);
|
||||
|
||||
/// <summary>
|
||||
/// 设置默认事件处理函数。
|
||||
/// </summary>
|
||||
/// <param name="handler">要设置的默认事件处理函数。</param>
|
||||
void SetDefaultHandler(EventHandler<GameEventArgs> handler);
|
||||
|
||||
/// <summary>
|
||||
/// 抛出事件,这个操作是线程安全的,即使不在主线程中抛出,也可保证在主线程中回调事件处理函数,但事件会在抛出后的下一帧分发。
|
||||
/// </summary>
|
||||
/// <param name="sender">事件源。</param>
|
||||
/// <param name="e">事件参数。</param>
|
||||
void Fire(object sender, GameEventArgs e);
|
||||
|
||||
/// <summary>
|
||||
/// 抛出事件立即模式,这个操作不是线程安全的,事件会立刻分发。
|
||||
/// </summary>
|
||||
/// <param name="sender">事件源。</param>
|
||||
/// <param name="e">事件参数。</param>
|
||||
void FireNow(object sender, GameEventArgs e);
|
||||
|
||||
/// <summary>
|
||||
/// 事件管理器轮询。
|
||||
/// </summary>
|
||||
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
|
||||
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
|
||||
void Update(float elapseSeconds, float realElapseSeconds);
|
||||
|
||||
/// <summary>
|
||||
/// 关闭并清理事件管理器。
|
||||
/// </summary>
|
||||
void Shutdown();
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 056d52252266e8f419ec195f7908a878
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,129 +0,0 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
public class NetEvent:BehaviourSingleton<NetEvent>
|
||||
{
|
||||
private IEventManager m_EventManager = null;
|
||||
|
||||
/// <summary>
|
||||
/// 获取事件处理函数的数量。
|
||||
/// </summary>
|
||||
public int EventHandlerCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_EventManager.EventHandlerCount;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取事件数量。
|
||||
/// </summary>
|
||||
public int EventCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_EventManager.EventCount;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
m_EventManager = new EventManager();
|
||||
if (m_EventManager == null)
|
||||
{
|
||||
Log.Fatal("Event manager is invalid.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if (m_EventManager != null)
|
||||
{
|
||||
m_EventManager.Update(Time.deltaTime, Time.unscaledDeltaTime);;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Destroy()
|
||||
{
|
||||
base.Destroy();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取事件处理函数的数量。
|
||||
/// </summary>
|
||||
/// <param name="id">事件类型编号。</param>
|
||||
/// <returns>事件处理函数的数量。</returns>
|
||||
public int Count(int id)
|
||||
{
|
||||
return m_EventManager.Count(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在事件处理函数。
|
||||
/// </summary>
|
||||
/// <param name="id">事件类型编号。</param>
|
||||
/// <param name="handler">要检查的事件处理函数。</param>
|
||||
/// <returns>是否存在事件处理函数。</returns>
|
||||
public bool Check(int id, EventHandler<GameEventArgs> handler)
|
||||
{
|
||||
return m_EventManager.Check(id, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 订阅事件处理回调函数。
|
||||
/// </summary>
|
||||
/// <param name="id">事件类型编号。</param>
|
||||
/// <param name="handler">要订阅的事件处理回调函数。</param>
|
||||
public void Subscribe(int id, EventHandler<GameEventArgs> handler)
|
||||
{
|
||||
m_EventManager.Subscribe(id, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取消订阅事件处理回调函数。
|
||||
/// </summary>
|
||||
/// <param name="id">事件类型编号。</param>
|
||||
/// <param name="handler">要取消订阅的事件处理回调函数。</param>
|
||||
public void Unsubscribe(int id, EventHandler<GameEventArgs> handler)
|
||||
{
|
||||
m_EventManager.Unsubscribe(id, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置默认事件处理函数。
|
||||
/// </summary>
|
||||
/// <param name="handler">要设置的默认事件处理函数。</param>
|
||||
public void SetDefaultHandler(EventHandler<GameEventArgs> handler)
|
||||
{
|
||||
m_EventManager.SetDefaultHandler(handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 抛出事件,这个操作是线程安全的,即使不在主线程中抛出,也可保证在主线程中回调事件处理函数,但事件会在抛出后的下一帧分发。
|
||||
/// </summary>
|
||||
/// <param name="sender">事件发送者。</param>
|
||||
/// <param name="e">事件内容。</param>
|
||||
public void Fire(object sender, GameEventArgs e)
|
||||
{
|
||||
m_EventManager.Fire(sender, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 抛出事件立即模式,这个操作不是线程安全的,事件会立刻分发。
|
||||
/// </summary>
|
||||
/// <param name="sender">事件发送者。</param>
|
||||
/// <param name="e">事件内容。</param>
|
||||
public void FireNow(object sender, GameEventArgs e)
|
||||
{
|
||||
m_EventManager.FireNow(sender, e);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4e42aa2c6d194fd59c82dc3c597d9152
|
||||
timeCreated: 1661775598
|
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9de71dee8e9fb74469064a1e1cf7a77b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,7 +0,0 @@
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
public abstract class CSPacketBase : PacketBase
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae0dc3216c53aaa4bb05456c6acc64f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,11 +0,0 @@
|
||||
using System;
|
||||
using ProtoBuf;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
[Serializable, ProtoContract(Name = @"CSPacketHeader")]
|
||||
public sealed class CSPacketHeader : PacketHeaderBase
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 383e04755715b054f9e57b1ab1d322af
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,256 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using ProtoBuf;
|
||||
using ProtoBuf.Meta;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
public class NetworkChannelHelper : INetworkChannelHelper
|
||||
{
|
||||
private readonly Dictionary<int, Type> m_ServerToClientPacketTypes = new Dictionary<int, Type>();
|
||||
private readonly MemoryStream m_CachedStream = new MemoryStream(1024 * 8);
|
||||
private INetworkChannel m_NetworkChannel = null;
|
||||
|
||||
/// <summary>
|
||||
/// 获取消息包头长度。
|
||||
/// </summary>
|
||||
public int PacketHeaderLength => sizeof(int);
|
||||
|
||||
/// <summary>
|
||||
/// 初始化网络频道辅助器。
|
||||
/// </summary>
|
||||
/// <param name="networkChannel">网络频道。</param>
|
||||
public void Initialize(INetworkChannel networkChannel)
|
||||
{
|
||||
m_NetworkChannel = networkChannel;
|
||||
|
||||
// 反射注册包和包处理函数。
|
||||
Type packetBaseType = typeof(CSPacketBase);
|
||||
Type packetHandlerBaseType = typeof(PacketHandlerBase);
|
||||
Assembly assembly = Assembly.GetExecutingAssembly();
|
||||
Type[] types = assembly.GetTypes();
|
||||
for (int i = 0; i < types.Length; i++)
|
||||
{
|
||||
if (!types[i].IsClass || types[i].IsAbstract)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (types[i].BaseType == packetBaseType)
|
||||
{
|
||||
PacketBase packetBase = (PacketBase)Activator.CreateInstance(types[i]);
|
||||
Type packetType = GetServerToClientPacketType(packetBase.Id);
|
||||
if (packetType != null)
|
||||
{
|
||||
Log.Warning("Already exist packet type '{0}', check '{1}' or '{2}'?.", packetBase.Id.ToString(), packetType.Name, packetBase.GetType().Name);
|
||||
continue;
|
||||
}
|
||||
|
||||
m_ServerToClientPacketTypes.Add(packetBase.Id, types[i]);
|
||||
}
|
||||
else if (types[i].BaseType == packetHandlerBaseType)
|
||||
{
|
||||
IPacketHandler packetHandler = (IPacketHandler)Activator.CreateInstance(types[i]);
|
||||
m_NetworkChannel.RegisterHandler(packetHandler);
|
||||
}
|
||||
}
|
||||
|
||||
NetEvent.Instance.Subscribe(NetworkConnectedEvent.EventId, OnNetworkConnected);
|
||||
NetEvent.Instance.Subscribe(NetworkClosedEvent.EventId, OnNetworkClosed);
|
||||
NetEvent.Instance.Subscribe(NetworkMissHeartBeatEvent.EventId, OnNetworkMissHeartBeat);
|
||||
NetEvent.Instance.Subscribe(NetworkErrorEvent.EventId, OnNetworkError);
|
||||
NetEvent.Instance.Subscribe(NetworkCustomErrorEvent.EventId, OnNetworkCustomError);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 准备进行连接。
|
||||
/// </summary>
|
||||
public void PrepareForConnecting()
|
||||
{
|
||||
m_NetworkChannel.Socket.ReceiveBufferSize = 1024 * 64;
|
||||
m_NetworkChannel.Socket.SendBufferSize = 1024 * 64;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送心跳消息包。
|
||||
/// </summary>
|
||||
/// <returns>是否发送心跳消息包成功。</returns>
|
||||
public bool SendHeartBeat()
|
||||
{
|
||||
m_NetworkChannel.Send(MemoryPool.Acquire<CSHeartBeat>());
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 序列化消息包。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">消息包类型。</typeparam>
|
||||
/// <param name="packet">要序列化的消息包。</param>
|
||||
/// <param name="destination">要序列化的目标流。</param>
|
||||
/// <returns>是否序列化成功。</returns>
|
||||
public bool Serialize<T>(T packet, Stream destination) where T : Packet
|
||||
{
|
||||
PacketBase packetImpl = packet as PacketBase;
|
||||
if (packetImpl == null)
|
||||
{
|
||||
Log.Warning("Packet is invalid.");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_CachedStream.SetLength(m_CachedStream.Capacity); // 此行防止 Array.Copy 的数据无法写入
|
||||
m_CachedStream.Position = 0L;
|
||||
|
||||
CSPacketHeader packetHeader = MemoryPool.Acquire<CSPacketHeader>();
|
||||
Serializer.Serialize(m_CachedStream, packetHeader);
|
||||
MemoryPool.Release(packetHeader);
|
||||
|
||||
Serializer.SerializeWithLengthPrefix(m_CachedStream, packet, PrefixStyle.Fixed32);
|
||||
MemoryPool.Release((IMemory)packet);
|
||||
|
||||
m_CachedStream.WriteTo(destination);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化消息包。
|
||||
/// </summary>
|
||||
/// <param name="packetHeader">消息包头。</param>
|
||||
/// <param name="source">要反序列化的来源流。</param>
|
||||
/// <param name="customErrorData">用户自定义错误数据。</param>
|
||||
/// <returns>反序列化后的消息包。</returns>
|
||||
public Packet DeserializePacket(IPacketHeader packetHeader, Stream source, out object customErrorData)
|
||||
{
|
||||
// 注意:此函数并不在主线程调用!
|
||||
customErrorData = null;
|
||||
|
||||
CSPacketHeader csPacketHeader = packetHeader as CSPacketHeader;
|
||||
if (csPacketHeader == null)
|
||||
{
|
||||
Log.Warning("Packet header is invalid.");
|
||||
return null;
|
||||
}
|
||||
|
||||
Packet packet = null;
|
||||
if (csPacketHeader.IsValid)
|
||||
{
|
||||
Type packetType = GetServerToClientPacketType(csPacketHeader.Id);
|
||||
if (packetType != null)
|
||||
{
|
||||
packet = (Packet)RuntimeTypeModel.Default.DeserializeWithLengthPrefix(source, MemoryPool.Acquire(packetType), packetType, PrefixStyle.Fixed32, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Warning("Can not deserialize packet for packet id '{0}'.", csPacketHeader.Id.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Warning("Packet header is invalid.");
|
||||
}
|
||||
|
||||
MemoryPool.Release(csPacketHeader);
|
||||
return packet;
|
||||
}
|
||||
|
||||
public IPacketHeader DeserializePacketHeader(Stream source, out object customErrorData)
|
||||
{
|
||||
// 注意:此函数并不在主线程调用!
|
||||
customErrorData = null;
|
||||
return (IPacketHeader)RuntimeTypeModel.Default.Deserialize(source, MemoryPool.Acquire<CSPacketHeader>(), typeof(CSPacketHeader));
|
||||
}
|
||||
|
||||
private Type GetServerToClientPacketType(int id)
|
||||
{
|
||||
Type type = null;
|
||||
if (m_ServerToClientPacketTypes.TryGetValue(id, out type))
|
||||
{
|
||||
return type;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭并清理网络频道辅助器。
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
NetEvent.Instance.Unsubscribe(NetworkConnectedEvent.EventId, OnNetworkConnected);
|
||||
NetEvent.Instance.Unsubscribe(NetworkClosedEvent.EventId, OnNetworkClosed);
|
||||
NetEvent.Instance.Unsubscribe(NetworkMissHeartBeatEvent.EventId, OnNetworkMissHeartBeat);
|
||||
NetEvent.Instance.Unsubscribe(NetworkErrorEvent.EventId, OnNetworkError);
|
||||
NetEvent.Instance.Unsubscribe(NetworkCustomErrorEvent.EventId, OnNetworkCustomError);
|
||||
|
||||
m_NetworkChannel = null;
|
||||
}
|
||||
|
||||
#region Handle
|
||||
private void OnNetworkConnected(object sender, GameEventArgs e)
|
||||
{
|
||||
NetworkConnectedEvent ne = (NetworkConnectedEvent)e;
|
||||
if (ne.NetworkChannel != m_NetworkChannel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ne.NetworkChannel.Socket == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Log.Info("Network channel '{0}' connected, local address '{1}', remote address '{2}'.", ne.NetworkChannel.Name, ne.NetworkChannel.Socket.LocalEndPoint.ToString(), ne.NetworkChannel.Socket.RemoteEndPoint.ToString());
|
||||
}
|
||||
|
||||
private void OnNetworkClosed(object sender, GameEventArgs e)
|
||||
{
|
||||
NetworkClosedEvent ne = (NetworkClosedEvent)e;
|
||||
if (ne.NetworkChannel != m_NetworkChannel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Log.Warning("Network channel '{0}' closed.", ne.NetworkChannel.Name);
|
||||
}
|
||||
|
||||
private void OnNetworkMissHeartBeat(object sender, GameEventArgs e)
|
||||
{
|
||||
NetworkMissHeartBeatEvent ne = (NetworkMissHeartBeatEvent)e;
|
||||
if (ne.NetworkChannel != m_NetworkChannel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Log.Warning("Network channel '{0}' miss heart beat '{1}' times.", ne.NetworkChannel.Name, ne.MissCount.ToString());
|
||||
|
||||
if (ne.MissCount < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ne.NetworkChannel.Close();
|
||||
}
|
||||
|
||||
private void OnNetworkError(object sender, GameEventArgs e)
|
||||
{
|
||||
NetworkErrorEvent ne = (NetworkErrorEvent)e;
|
||||
if (ne.NetworkChannel != m_NetworkChannel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Log.Fatal("Network channel '{0}' error, error code is '{1}', error message is '{2}'.", ne.NetworkChannel.Name, ne.ErrorCode.ToString(), ne.ErrorMessage);
|
||||
|
||||
ne.NetworkChannel.Close();
|
||||
}
|
||||
|
||||
private void OnNetworkCustomError(object sender, GameEventArgs e)
|
||||
{
|
||||
NetworkCustomErrorEvent ne = (NetworkCustomErrorEvent)e;
|
||||
if (ne.NetworkChannel != m_NetworkChannel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Log.Fatal("Network channel '{0}' error, error code is '{1}', error message is '{2}'.", ne.NetworkChannel.Name, ne.CustomErrorData.ToString());
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02d761e658b2dcd4ea9ebff4ce324968
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 77278504198432741b5b1efb12e04803
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,19 +0,0 @@
|
||||
using System;
|
||||
using ProtoBuf;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
[Serializable, ProtoContract(Name = @"CSHeartBeat")]
|
||||
public class CSHeartBeat : CSPacketBase
|
||||
{
|
||||
public CSHeartBeat()
|
||||
{
|
||||
}
|
||||
|
||||
public override int Id => 1;
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0df96c80b0460c24fad98087851fd96c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,19 +0,0 @@
|
||||
using ProtoBuf;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
public abstract class PacketBase : Packet, IExtensible
|
||||
{
|
||||
private IExtension m_ExtensionObject;
|
||||
|
||||
public PacketBase()
|
||||
{
|
||||
m_ExtensionObject = null;
|
||||
}
|
||||
|
||||
IExtension IExtensible.GetExtensionObject(bool createIfMissing)
|
||||
{
|
||||
return Extensible.GetExtensionObject(ref m_ExtensionObject, createIfMissing);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e8f72df0df1102a4493aac4a082edb0a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0396e29af93d424fb252e3cf5a948fa6
|
||||
timeCreated: 1661850708
|
@@ -1,27 +0,0 @@
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 心跳Handler
|
||||
/// </summary>
|
||||
public class CSHeartBeatHandler : PacketHandlerBase
|
||||
{
|
||||
public override int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Handle(object sender, Packet packet)
|
||||
{
|
||||
CSHeartBeat packetImpl = (CSHeartBeat)packet;
|
||||
if (packetImpl == null)
|
||||
{
|
||||
Log.Fatal("Receive CSHeartBeat Failed !!!");
|
||||
return;
|
||||
}
|
||||
Log.Info("Receive packet '{0}'.", packetImpl.Id.ToString());
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 553b96ca58c647d39802bed84a356608
|
||||
timeCreated: 1661850718
|
@@ -1,15 +0,0 @@
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// PacketHandler处理,TEngine.Runtime程序集内无需手动注册,实现即可
|
||||
/// </summary>
|
||||
public abstract class PacketHandlerBase : IPacketHandler
|
||||
{
|
||||
public abstract int Id
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
public abstract void Handle(object sender, Packet packet);
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6da38694044dff944af5213c4cb2d413
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,31 +0,0 @@
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
public abstract class PacketHeaderBase : IPacketHeader, IMemory
|
||||
{
|
||||
public int Id
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public int PacketLength
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public bool IsValid
|
||||
{
|
||||
get
|
||||
{
|
||||
return Id > 0 && PacketLength >= 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
Id = 0;
|
||||
PacketLength = 0;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 279045bf4ec72144aa03880102a04057
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,49 +0,0 @@
|
||||
using System.IO;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
public class ProtoUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// 序列化 MainPack -> byte[]
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="mainPack"></param>
|
||||
/// <returns></returns>
|
||||
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)
|
||||
{
|
||||
Log.Error($"[Serialize] Error:{ex.Message}, {ex.Data["StackTrace"]}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="buffer"></param>
|
||||
/// <returns></returns>
|
||||
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)
|
||||
{
|
||||
Log.Error(($"[DeSerialize] Error:{ex.Message}, {ex.Data["StackTrace"]}"));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ab82c8abf14856489102fe60cc78926
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,157 +0,0 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络频道接口。
|
||||
/// </summary>
|
||||
public interface INetworkChannel
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取网络频道名称。
|
||||
/// </summary>
|
||||
string Name
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络频道所使用的 Socket。
|
||||
/// </summary>
|
||||
Socket Socket
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取是否已连接。
|
||||
/// </summary>
|
||||
bool Connected
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络服务类型。
|
||||
/// </summary>
|
||||
ServiceType ServiceType
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络地址类型。
|
||||
/// </summary>
|
||||
AddressFamily AddressFamily
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取要发送的消息包数量。
|
||||
/// </summary>
|
||||
int SendPacketCount
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取累计发送的消息包数量。
|
||||
/// </summary>
|
||||
int SentPacketCount
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取已接收未处理的消息包数量。
|
||||
/// </summary>
|
||||
int ReceivePacketCount
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取累计已接收的消息包数量。
|
||||
/// </summary>
|
||||
int ReceivedPacketCount
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置当收到消息包时是否重置心跳流逝时间。
|
||||
/// </summary>
|
||||
bool ResetHeartBeatElapseSecondsWhenReceivePacket
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取丢失心跳的次数。
|
||||
/// </summary>
|
||||
int MissHeartBeatCount
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置心跳间隔时长,以秒为单位。
|
||||
/// </summary>
|
||||
float HeartBeatInterval
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取心跳等待时长,以秒为单位。
|
||||
/// </summary>
|
||||
float HeartBeatElapseSeconds
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册网络消息包处理函数。
|
||||
/// </summary>
|
||||
/// <param name="handler">要注册的网络消息包处理函数。</param>
|
||||
void RegisterHandler(IPacketHandler handler);
|
||||
|
||||
/// <summary>
|
||||
/// 设置默认事件处理函数。
|
||||
/// </summary>
|
||||
/// <param name="handler">要设置的默认事件处理函数。</param>
|
||||
void SetDefaultHandler(EventHandler<Packet> handler);
|
||||
|
||||
/// <summary>
|
||||
/// 连接到远程主机。
|
||||
/// </summary>
|
||||
/// <param name="ipAddress">远程主机的 IP 地址。</param>
|
||||
/// <param name="port">远程主机的端口号。</param>
|
||||
void Connect(IPAddress ipAddress, int port);
|
||||
|
||||
/// <summary>
|
||||
/// 连接到远程主机。
|
||||
/// </summary>
|
||||
/// <param name="ipAddress">远程主机的 IP 地址。</param>
|
||||
/// <param name="port">远程主机的端口号。</param>
|
||||
/// <param name="userData">用户自定义数据。</param>
|
||||
void Connect(IPAddress ipAddress, int port, object userData);
|
||||
|
||||
/// <summary>
|
||||
/// 关闭网络频道。
|
||||
/// </summary>
|
||||
void Close();
|
||||
|
||||
/// <summary>
|
||||
/// 向远程主机发送消息包。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">消息包类型。</typeparam>
|
||||
/// <param name="packet">要发送的消息包。</param>
|
||||
void Send<T>(T packet) where T : Packet;
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c66ee24862094df49e089d63f7481285
|
||||
timeCreated: 1661771701
|
@@ -1,66 +0,0 @@
|
||||
using System.IO;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络频道辅助器接口。
|
||||
/// </summary>
|
||||
public interface INetworkChannelHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取消息包头长度。
|
||||
/// </summary>
|
||||
int PacketHeaderLength
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化网络频道辅助器。
|
||||
/// </summary>
|
||||
/// <param name="networkChannel">网络频道。</param>
|
||||
void Initialize(INetworkChannel networkChannel);
|
||||
|
||||
/// <summary>
|
||||
/// 关闭并清理网络频道辅助器。
|
||||
/// </summary>
|
||||
void Shutdown();
|
||||
|
||||
/// <summary>
|
||||
/// 准备进行连接。
|
||||
/// </summary>
|
||||
void PrepareForConnecting();
|
||||
|
||||
/// <summary>
|
||||
/// 发送心跳消息包。
|
||||
/// </summary>
|
||||
/// <returns>是否发送心跳消息包成功。</returns>
|
||||
bool SendHeartBeat();
|
||||
|
||||
/// <summary>
|
||||
/// 序列化消息包。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">消息包类型。</typeparam>
|
||||
/// <param name="packet">要序列化的消息包。</param>
|
||||
/// <param name="destination">要序列化的目标流。</param>
|
||||
/// <returns>是否序列化成功。</returns>
|
||||
bool Serialize<T>(T packet, Stream destination) where T : Packet;
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化消息包头。
|
||||
/// </summary>
|
||||
/// <param name="source">要反序列化的来源流。</param>
|
||||
/// <param name="customErrorData">用户自定义错误数据。</param>
|
||||
/// <returns>反序列化后的消息包头。</returns>
|
||||
IPacketHeader DeserializePacketHeader(Stream source, out object customErrorData);
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化消息包。
|
||||
/// </summary>
|
||||
/// <param name="packetHeader">消息包头。</param>
|
||||
/// <param name="source">要反序列化的来源流。</param>
|
||||
/// <param name="customErrorData">用户自定义错误数据。</param>
|
||||
/// <returns>反序列化后的消息包。</returns>
|
||||
Packet DeserializePacket(IPacketHeader packetHeader, Stream source, out object customErrorData);
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aeff0f53fdd54bd489d6a6141e79dca0
|
||||
timeCreated: 1661771934
|
@@ -1,86 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络管理器接口。
|
||||
/// </summary>
|
||||
public interface INetworkManager
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取网络频道数量。
|
||||
/// </summary>
|
||||
int NetworkChannelCount
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 网络连接成功事件。
|
||||
/// </summary>
|
||||
event EventHandler<NetworkConnectedEventArgs> NetworkConnected;
|
||||
|
||||
/// <summary>
|
||||
/// 网络连接关闭事件。
|
||||
/// </summary>
|
||||
event EventHandler<NetworkClosedEventArgs> NetworkClosed;
|
||||
|
||||
/// <summary>
|
||||
/// 网络心跳包丢失事件。
|
||||
/// </summary>
|
||||
event EventHandler<NetworkMissHeartBeatEventArgs> NetworkMissHeartBeat;
|
||||
|
||||
/// <summary>
|
||||
/// 网络错误事件。
|
||||
/// </summary>
|
||||
event EventHandler<NetworkErrorEventArgs> NetworkError;
|
||||
|
||||
/// <summary>
|
||||
/// 用户自定义网络错误事件。
|
||||
/// </summary>
|
||||
event EventHandler<NetworkCustomErrorEventArgs> NetworkCustomError;
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在网络频道。
|
||||
/// </summary>
|
||||
/// <param name="name">网络频道名称。</param>
|
||||
/// <returns>是否存在网络频道。</returns>
|
||||
bool HasNetworkChannel(string name);
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络频道。
|
||||
/// </summary>
|
||||
/// <param name="name">网络频道名称。</param>
|
||||
/// <returns>要获取的网络频道。</returns>
|
||||
INetworkChannel GetNetworkChannel(string name);
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有网络频道。
|
||||
/// </summary>
|
||||
/// <returns>所有网络频道。</returns>
|
||||
INetworkChannel[] GetAllNetworkChannels();
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有网络频道。
|
||||
/// </summary>
|
||||
/// <param name="results">所有网络频道。</param>
|
||||
void GetAllNetworkChannels(List<INetworkChannel> results);
|
||||
|
||||
/// <summary>
|
||||
/// 创建网络频道。
|
||||
/// </summary>
|
||||
/// <param name="name">网络频道名称。</param>
|
||||
/// <param name="serviceType">网络服务类型。</param>
|
||||
/// <param name="networkChannelHelper">网络频道辅助器。</param>
|
||||
/// <returns>要创建的网络频道。</returns>
|
||||
INetworkChannel CreateNetworkChannel(string name, ServiceType serviceType, INetworkChannelHelper networkChannelHelper);
|
||||
|
||||
/// <summary>
|
||||
/// 销毁网络频道。
|
||||
/// </summary>
|
||||
/// <param name="name">网络频道名称。</param>
|
||||
/// <returns>是否销毁网络频道成功。</returns>
|
||||
bool DestroyNetworkChannel(string name);
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa9566de56cd4b579631a1725b89174e
|
||||
timeCreated: 1661775465
|
@@ -1,23 +0,0 @@
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络消息包处理器接口。
|
||||
/// </summary>
|
||||
public interface IPacketHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取网络消息包协议编号。
|
||||
/// </summary>
|
||||
int Id
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 网络消息包处理函数。
|
||||
/// </summary>
|
||||
/// <param name="sender">网络消息包源。</param>
|
||||
/// <param name="packet">网络消息包内容。</param>
|
||||
void Handle(object sender, Packet packet);
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 49d9ce041dfb4dc98f954dd85e7b9015
|
||||
timeCreated: 1661771824
|
@@ -1,16 +0,0 @@
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络消息包头接口。
|
||||
/// </summary>
|
||||
public interface IPacketHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取网络消息包长度。
|
||||
/// </summary>
|
||||
int PacketLength
|
||||
{
|
||||
get;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a61d331daf74fe48bffbb083f016cb5
|
||||
timeCreated: 1661771898
|
@@ -1,163 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络组件。
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
[AddComponentMenu("TEngine/Network")]
|
||||
public class Network : UnitySingleton<Network>
|
||||
{
|
||||
private INetworkManager m_NetworkManager = null;
|
||||
|
||||
public NetworkManager NetworkManager
|
||||
{
|
||||
private set;
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络频道数量。
|
||||
/// </summary>
|
||||
public int NetworkChannelCount
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_NetworkManager == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return m_NetworkManager.NetworkChannelCount;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnLoad()
|
||||
{
|
||||
base.OnLoad();
|
||||
m_NetworkManager = new NetworkManager();
|
||||
NetworkManager = m_NetworkManager as NetworkManager;
|
||||
if (m_NetworkManager == null)
|
||||
{
|
||||
Log.Fatal("Network manager is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_NetworkManager.NetworkConnected += OnNetworkConnected;
|
||||
m_NetworkManager.NetworkClosed += OnNetworkClosed;
|
||||
m_NetworkManager.NetworkMissHeartBeat += OnNetworkMissHeartBeat;
|
||||
m_NetworkManager.NetworkError += OnNetworkError;
|
||||
m_NetworkManager.NetworkCustomError += OnNetworkCustomError;
|
||||
|
||||
if (NetEvent.Instance == null)
|
||||
{
|
||||
Log.Fatal("Event component is invalid.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (m_NetworkManager != null)
|
||||
{
|
||||
NetworkManager.Update(Time.deltaTime, Time.unscaledDeltaTime);;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
if (NetworkManager != null)
|
||||
{
|
||||
NetworkManager.Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在网络频道。
|
||||
/// </summary>
|
||||
/// <param name="name">网络频道名称。</param>
|
||||
/// <returns>是否存在网络频道。</returns>
|
||||
public bool HasNetworkChannel(string name)
|
||||
{
|
||||
return m_NetworkManager.HasNetworkChannel(name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络频道。
|
||||
/// </summary>
|
||||
/// <param name="name">网络频道名称。</param>
|
||||
/// <returns>要获取的网络频道。</returns>
|
||||
public INetworkChannel GetNetworkChannel(string name)
|
||||
{
|
||||
return m_NetworkManager.GetNetworkChannel(name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有网络频道。
|
||||
/// </summary>
|
||||
/// <returns>所有网络频道。</returns>
|
||||
public INetworkChannel[] GetAllNetworkChannels()
|
||||
{
|
||||
return m_NetworkManager.GetAllNetworkChannels();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有网络频道。
|
||||
/// </summary>
|
||||
/// <param name="results">所有网络频道。</param>
|
||||
public void GetAllNetworkChannels(List<INetworkChannel> results)
|
||||
{
|
||||
m_NetworkManager.GetAllNetworkChannels(results);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建网络频道。
|
||||
/// </summary>
|
||||
/// <param name="name">网络频道名称。</param>
|
||||
/// <param name="serviceType">网络服务类型。</param>
|
||||
/// <param name="networkChannelHelper">网络频道辅助器。</param>
|
||||
/// <returns>要创建的网络频道。</returns>
|
||||
public INetworkChannel CreateNetworkChannel(string name, ServiceType serviceType, INetworkChannelHelper networkChannelHelper)
|
||||
{
|
||||
return m_NetworkManager.CreateNetworkChannel(name, serviceType, networkChannelHelper);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁网络频道。
|
||||
/// </summary>
|
||||
/// <param name="name">网络频道名称。</param>
|
||||
/// <returns>是否销毁网络频道成功。</returns>
|
||||
public bool DestroyNetworkChannel(string name)
|
||||
{
|
||||
return m_NetworkManager.DestroyNetworkChannel(name);
|
||||
}
|
||||
|
||||
private void OnNetworkConnected(object sender, NetworkConnectedEventArgs e)
|
||||
{
|
||||
NetEvent.Instance.Fire(this, NetworkConnectedEvent.Create(e));
|
||||
}
|
||||
|
||||
private void OnNetworkClosed(object sender, NetworkClosedEventArgs e)
|
||||
{
|
||||
NetEvent.Instance.Fire(this, NetworkClosedEvent.Create(e));
|
||||
}
|
||||
|
||||
private void OnNetworkMissHeartBeat(object sender, NetworkMissHeartBeatEventArgs e)
|
||||
{
|
||||
NetEvent.Instance.Fire(this, NetworkMissHeartBeatEvent.Create(e));
|
||||
}
|
||||
|
||||
private void OnNetworkError(object sender, NetworkErrorEventArgs e)
|
||||
{
|
||||
NetEvent.Instance.Fire(this, NetworkErrorEvent.Create(e));
|
||||
}
|
||||
|
||||
private void OnNetworkCustomError(object sender, NetworkCustomErrorEventArgs e)
|
||||
{
|
||||
NetEvent.Instance.Fire(this, NetworkCustomErrorEvent.Create(e));
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1dd2b00e963a5b54db7aae1b87628982
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,53 +0,0 @@
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络错误码。
|
||||
/// </summary>
|
||||
public enum NetworkErrorCode : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// 未知错误。
|
||||
/// </summary>
|
||||
Unknown = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 地址族错误。
|
||||
/// </summary>
|
||||
AddressFamilyError,
|
||||
|
||||
/// <summary>
|
||||
/// Socket 错误。
|
||||
/// </summary>
|
||||
SocketError,
|
||||
|
||||
/// <summary>
|
||||
/// 连接错误。
|
||||
/// </summary>
|
||||
ConnectError,
|
||||
|
||||
/// <summary>
|
||||
/// 发送错误。
|
||||
/// </summary>
|
||||
SendError,
|
||||
|
||||
/// <summary>
|
||||
/// 接收错误。
|
||||
/// </summary>
|
||||
ReceiveError,
|
||||
|
||||
/// <summary>
|
||||
/// 序列化错误。
|
||||
/// </summary>
|
||||
SerializeError,
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化消息包头错误。
|
||||
/// </summary>
|
||||
DeserializePacketHeaderError,
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化消息包错误。
|
||||
/// </summary>
|
||||
DeserializePacketError
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86fe9208ee30402ab1fcdc8cdcff1d89
|
||||
timeCreated: 1661771970
|
@@ -1,35 +0,0 @@
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
public sealed partial class NetworkManager
|
||||
{
|
||||
private sealed class ConnectState
|
||||
{
|
||||
private readonly Socket m_Socket;
|
||||
private readonly object m_UserData;
|
||||
|
||||
public ConnectState(Socket socket, object userData)
|
||||
{
|
||||
m_Socket = socket;
|
||||
m_UserData = userData;
|
||||
}
|
||||
|
||||
public Socket Socket
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Socket;
|
||||
}
|
||||
}
|
||||
|
||||
public object UserData
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_UserData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07167c4e7b24c2148acdfe52fbe0c817
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,51 +0,0 @@
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
public sealed partial class NetworkManager
|
||||
{
|
||||
private sealed class HeartBeatState
|
||||
{
|
||||
private float m_HeartBeatElapseSeconds;
|
||||
private int m_MissHeartBeatCount;
|
||||
|
||||
public HeartBeatState()
|
||||
{
|
||||
m_HeartBeatElapseSeconds = 0f;
|
||||
m_MissHeartBeatCount = 0;
|
||||
}
|
||||
|
||||
public float HeartBeatElapseSeconds
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_HeartBeatElapseSeconds;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_HeartBeatElapseSeconds = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int MissHeartBeatCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_MissHeartBeatCount;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_MissHeartBeatCount = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset(bool resetHeartBeatElapseSeconds)
|
||||
{
|
||||
if (resetHeartBeatElapseSeconds)
|
||||
{
|
||||
m_HeartBeatElapseSeconds = 0f;
|
||||
}
|
||||
|
||||
m_MissHeartBeatCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e1beec3505229bd418c252c142a01152
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,629 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
public sealed partial class NetworkManager
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络频道基类。
|
||||
/// </summary>
|
||||
private abstract class NetworkChannelBase : INetworkChannel, IDisposable
|
||||
{
|
||||
private const float DefaultHeartBeatInterval = 30f;
|
||||
|
||||
private readonly string m_Name;
|
||||
protected readonly Queue<Packet> m_SendPacketPool;
|
||||
protected readonly EventPool<Packet> m_ReceivePacketPool;
|
||||
protected readonly INetworkChannelHelper m_NetworkChannelHelper;
|
||||
protected AddressFamily m_AddressFamily;
|
||||
protected bool m_ResetHeartBeatElapseSecondsWhenReceivePacket;
|
||||
protected float m_HeartBeatInterval;
|
||||
protected Socket m_Socket;
|
||||
protected readonly SendState m_SendState;
|
||||
protected readonly ReceiveState m_ReceiveState;
|
||||
protected readonly HeartBeatState m_HeartBeatState;
|
||||
protected int m_SentPacketCount;
|
||||
protected int m_ReceivedPacketCount;
|
||||
protected bool m_Active;
|
||||
private bool m_Disposed;
|
||||
|
||||
public Action<NetworkChannelBase, object> NetworkChannelConnected;
|
||||
public Action<NetworkChannelBase> NetworkChannelClosed;
|
||||
public Action<NetworkChannelBase, int> NetworkChannelMissHeartBeat;
|
||||
public Action<NetworkChannelBase, NetworkErrorCode, SocketError, string> NetworkChannelError;
|
||||
public Action<NetworkChannelBase, object> NetworkChannelCustomError;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化网络频道基类的新实例。
|
||||
/// </summary>
|
||||
/// <param name="name">网络频道名称。</param>
|
||||
/// <param name="networkChannelHelper">网络频道辅助器。</param>
|
||||
public NetworkChannelBase(string name, INetworkChannelHelper networkChannelHelper)
|
||||
{
|
||||
m_Name = name ?? string.Empty;
|
||||
m_SendPacketPool = new Queue<Packet>();
|
||||
m_ReceivePacketPool = new EventPool<Packet>(EventPoolMode.Default);
|
||||
m_NetworkChannelHelper = networkChannelHelper;
|
||||
m_AddressFamily = AddressFamily.Unknown;
|
||||
m_ResetHeartBeatElapseSecondsWhenReceivePacket = false;
|
||||
m_HeartBeatInterval = DefaultHeartBeatInterval;
|
||||
m_Socket = null;
|
||||
m_SendState = new SendState();
|
||||
m_ReceiveState = new ReceiveState();
|
||||
m_HeartBeatState = new HeartBeatState();
|
||||
m_SentPacketCount = 0;
|
||||
m_ReceivedPacketCount = 0;
|
||||
m_Active = false;
|
||||
m_Disposed = false;
|
||||
|
||||
NetworkChannelConnected = null;
|
||||
NetworkChannelClosed = null;
|
||||
NetworkChannelMissHeartBeat = null;
|
||||
NetworkChannelError = null;
|
||||
NetworkChannelCustomError = null;
|
||||
|
||||
networkChannelHelper.Initialize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络频道名称。
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络频道所使用的 Socket。
|
||||
/// </summary>
|
||||
public Socket Socket
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Socket;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取是否已连接。
|
||||
/// </summary>
|
||||
public bool Connected
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Socket != null)
|
||||
{
|
||||
return m_Socket.Connected;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络服务类型。
|
||||
/// </summary>
|
||||
public abstract ServiceType ServiceType
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络地址类型。
|
||||
/// </summary>
|
||||
public AddressFamily AddressFamily
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_AddressFamily;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取要发送的消息包数量。
|
||||
/// </summary>
|
||||
public int SendPacketCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_SendPacketPool.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取累计发送的消息包数量。
|
||||
/// </summary>
|
||||
public int SentPacketCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_SentPacketCount;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取已接收未处理的消息包数量。
|
||||
/// </summary>
|
||||
public int ReceivePacketCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_ReceivePacketPool.EventCount;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取累计已接收的消息包数量。
|
||||
/// </summary>
|
||||
public int ReceivedPacketCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_ReceivedPacketCount;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置当收到消息包时是否重置心跳流逝时间。
|
||||
/// </summary>
|
||||
public bool ResetHeartBeatElapseSecondsWhenReceivePacket
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_ResetHeartBeatElapseSecondsWhenReceivePacket;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_ResetHeartBeatElapseSecondsWhenReceivePacket = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取丢失心跳的次数。
|
||||
/// </summary>
|
||||
public int MissHeartBeatCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_HeartBeatState.MissHeartBeatCount;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置心跳间隔时长,以秒为单位。
|
||||
/// </summary>
|
||||
public float HeartBeatInterval
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_HeartBeatInterval;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_HeartBeatInterval = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取心跳等待时长,以秒为单位。
|
||||
/// </summary>
|
||||
public float HeartBeatElapseSeconds
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_HeartBeatState.HeartBeatElapseSeconds;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 网络频道轮询。
|
||||
/// </summary>
|
||||
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
|
||||
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
|
||||
public virtual void Update(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
if (m_Socket == null || !m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ProcessSend();
|
||||
ProcessReceive();
|
||||
if (m_Socket == null || !m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_ReceivePacketPool.Update(elapseSeconds, realElapseSeconds);
|
||||
|
||||
if (m_HeartBeatInterval > 0f)
|
||||
{
|
||||
bool sendHeartBeat = false;
|
||||
int missHeartBeatCount = 0;
|
||||
lock (m_HeartBeatState)
|
||||
{
|
||||
if (m_Socket == null || !m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_HeartBeatState.HeartBeatElapseSeconds += realElapseSeconds;
|
||||
if (m_HeartBeatState.HeartBeatElapseSeconds >= m_HeartBeatInterval)
|
||||
{
|
||||
sendHeartBeat = true;
|
||||
missHeartBeatCount = m_HeartBeatState.MissHeartBeatCount;
|
||||
m_HeartBeatState.HeartBeatElapseSeconds = 0f;
|
||||
m_HeartBeatState.MissHeartBeatCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (sendHeartBeat && m_NetworkChannelHelper.SendHeartBeat())
|
||||
{
|
||||
if (missHeartBeatCount > 0 && NetworkChannelMissHeartBeat != null)
|
||||
{
|
||||
NetworkChannelMissHeartBeat(this, missHeartBeatCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭网络频道。
|
||||
/// </summary>
|
||||
public virtual void Shutdown()
|
||||
{
|
||||
Close();
|
||||
m_ReceivePacketPool.Shutdown();
|
||||
m_NetworkChannelHelper.Shutdown();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册网络消息包处理函数。
|
||||
/// </summary>
|
||||
/// <param name="handler">要注册的网络消息包处理函数。</param>
|
||||
public void RegisterHandler(IPacketHandler handler)
|
||||
{
|
||||
if (handler == null)
|
||||
{
|
||||
throw new Exception("Packet handler is invalid.");
|
||||
}
|
||||
|
||||
m_ReceivePacketPool.Subscribe(handler.Id, handler.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置默认事件处理函数。
|
||||
/// </summary>
|
||||
/// <param name="handler">要设置的默认事件处理函数。</param>
|
||||
public void SetDefaultHandler(EventHandler<Packet> handler)
|
||||
{
|
||||
m_ReceivePacketPool.SetDefaultHandler(handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接到远程主机。
|
||||
/// </summary>
|
||||
/// <param name="ipAddress">远程主机的 IP 地址。</param>
|
||||
/// <param name="port">远程主机的端口号。</param>
|
||||
public void Connect(IPAddress ipAddress, int port)
|
||||
{
|
||||
Connect(ipAddress, port, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接到远程主机。
|
||||
/// </summary>
|
||||
/// <param name="ipAddress">远程主机的 IP 地址。</param>
|
||||
/// <param name="port">远程主机的端口号。</param>
|
||||
/// <param name="userData">用户自定义数据。</param>
|
||||
public virtual void Connect(IPAddress ipAddress, int port, object userData)
|
||||
{
|
||||
if (m_Socket != null)
|
||||
{
|
||||
Close();
|
||||
m_Socket = null;
|
||||
}
|
||||
|
||||
switch (ipAddress.AddressFamily)
|
||||
{
|
||||
case System.Net.Sockets.AddressFamily.InterNetwork:
|
||||
m_AddressFamily = AddressFamily.IPv4;
|
||||
break;
|
||||
|
||||
case System.Net.Sockets.AddressFamily.InterNetworkV6:
|
||||
m_AddressFamily = AddressFamily.IPv6;
|
||||
break;
|
||||
|
||||
default:
|
||||
string errorMessage = Utility.Text.Format("Not supported address family '{0}'.", ipAddress.AddressFamily);
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
NetworkChannelError(this, NetworkErrorCode.AddressFamilyError, SocketError.Success, errorMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Exception(errorMessage);
|
||||
}
|
||||
|
||||
m_SendState.Reset();
|
||||
m_ReceiveState.PrepareForPacketHeader(m_NetworkChannelHelper.PacketHeaderLength);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭连接并释放所有相关资源。
|
||||
/// </summary>
|
||||
public void Close()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (m_Socket == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_Active = false;
|
||||
|
||||
try
|
||||
{
|
||||
m_Socket.Shutdown(SocketShutdown.Both);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_Socket.Close();
|
||||
m_Socket = null;
|
||||
|
||||
if (NetworkChannelClosed != null)
|
||||
{
|
||||
NetworkChannelClosed(this);
|
||||
}
|
||||
}
|
||||
|
||||
m_SentPacketCount = 0;
|
||||
m_ReceivedPacketCount = 0;
|
||||
|
||||
lock (m_SendPacketPool)
|
||||
{
|
||||
m_SendPacketPool.Clear();
|
||||
}
|
||||
|
||||
m_ReceivePacketPool.Clear();
|
||||
|
||||
lock (m_HeartBeatState)
|
||||
{
|
||||
m_HeartBeatState.Reset(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向远程主机发送消息包。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">消息包类型。</typeparam>
|
||||
/// <param name="packet">要发送的消息包。</param>
|
||||
public void Send<T>(T packet) where T : Packet
|
||||
{
|
||||
if (m_Socket == null)
|
||||
{
|
||||
string errorMessage = "You must connect first.";
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
NetworkChannelError(this, NetworkErrorCode.SendError, SocketError.Success, errorMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Exception(errorMessage);
|
||||
}
|
||||
|
||||
if (!m_Active)
|
||||
{
|
||||
string errorMessage = "Socket is not active.";
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
NetworkChannelError(this, NetworkErrorCode.SendError, SocketError.Success, errorMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Exception(errorMessage);
|
||||
}
|
||||
|
||||
if (packet == null)
|
||||
{
|
||||
string errorMessage = "Packet is invalid.";
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
NetworkChannelError(this, NetworkErrorCode.SendError, SocketError.Success, errorMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Exception(errorMessage);
|
||||
}
|
||||
|
||||
lock (m_SendPacketPool)
|
||||
{
|
||||
m_SendPacketPool.Enqueue(packet);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放资源。
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放资源。
|
||||
/// </summary>
|
||||
/// <param name="disposing">释放资源标记。</param>
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (m_Disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
Close();
|
||||
m_SendState.Dispose();
|
||||
m_ReceiveState.Dispose();
|
||||
}
|
||||
|
||||
m_Disposed = true;
|
||||
}
|
||||
|
||||
protected virtual bool ProcessSend()
|
||||
{
|
||||
if (m_SendState.Stream.Length > 0 || m_SendPacketPool.Count <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
while (m_SendPacketPool.Count > 0)
|
||||
{
|
||||
Packet packet = null;
|
||||
lock (m_SendPacketPool)
|
||||
{
|
||||
packet = m_SendPacketPool.Dequeue();
|
||||
}
|
||||
|
||||
bool serializeResult = false;
|
||||
try
|
||||
{
|
||||
serializeResult = m_NetworkChannelHelper.Serialize(packet, m_SendState.Stream);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
m_Active = false;
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
SocketException socketException = exception as SocketException;
|
||||
NetworkChannelError(this, NetworkErrorCode.SerializeError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
if (!serializeResult)
|
||||
{
|
||||
string errorMessage = "Serialized packet failure.";
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
NetworkChannelError(this, NetworkErrorCode.SerializeError, SocketError.Success, errorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
throw new Exception(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
m_SendState.Stream.Position = 0L;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual void ProcessReceive()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual bool ProcessPacketHeader()
|
||||
{
|
||||
try
|
||||
{
|
||||
object customErrorData = null;
|
||||
IPacketHeader packetHeader = m_NetworkChannelHelper.DeserializePacketHeader(m_ReceiveState.Stream, out customErrorData);
|
||||
|
||||
if (customErrorData != null && NetworkChannelCustomError != null)
|
||||
{
|
||||
NetworkChannelCustomError(this, customErrorData);
|
||||
}
|
||||
|
||||
if (packetHeader == null)
|
||||
{
|
||||
string errorMessage = "Packet header is invalid.";
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
NetworkChannelError(this, NetworkErrorCode.DeserializePacketHeaderError, SocketError.Success, errorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
throw new Exception(errorMessage);
|
||||
}
|
||||
|
||||
m_ReceiveState.PrepareForPacket(packetHeader);
|
||||
if (packetHeader.PacketLength <= 0)
|
||||
{
|
||||
bool processSuccess = ProcessPacket();
|
||||
m_ReceivedPacketCount++;
|
||||
return processSuccess;
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
m_Active = false;
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
SocketException socketException = exception as SocketException;
|
||||
NetworkChannelError(this, NetworkErrorCode.DeserializePacketHeaderError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual bool ProcessPacket()
|
||||
{
|
||||
lock (m_HeartBeatState)
|
||||
{
|
||||
m_HeartBeatState.Reset(m_ResetHeartBeatElapseSecondsWhenReceivePacket);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
object customErrorData = null;
|
||||
Packet packet = m_NetworkChannelHelper.DeserializePacket(m_ReceiveState.PacketHeader, m_ReceiveState.Stream, out customErrorData);
|
||||
|
||||
if (customErrorData != null && NetworkChannelCustomError != null)
|
||||
{
|
||||
NetworkChannelCustomError(this, customErrorData);
|
||||
}
|
||||
|
||||
if (packet != null)
|
||||
{
|
||||
m_ReceivePacketPool.Fire(this, packet);
|
||||
}
|
||||
|
||||
m_ReceiveState.PrepareForPacketHeader(m_NetworkChannelHelper.PacketHeaderLength);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
m_Active = false;
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
SocketException socketException = exception as SocketException;
|
||||
NetworkChannelError(this, NetworkErrorCode.DeserializePacketError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d124c3d2afc7006459e261c8d510711c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,91 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
public sealed partial class NetworkManager
|
||||
{
|
||||
private sealed class ReceiveState : IDisposable
|
||||
{
|
||||
private const int DefaultBufferLength = 1024 * 64;
|
||||
private MemoryStream m_Stream;
|
||||
private IPacketHeader m_PacketHeader;
|
||||
private bool m_Disposed;
|
||||
|
||||
public ReceiveState()
|
||||
{
|
||||
m_Stream = new MemoryStream(DefaultBufferLength);
|
||||
m_PacketHeader = null;
|
||||
m_Disposed = false;
|
||||
}
|
||||
|
||||
public MemoryStream Stream
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Stream;
|
||||
}
|
||||
}
|
||||
|
||||
public IPacketHeader PacketHeader
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_PacketHeader;
|
||||
}
|
||||
}
|
||||
|
||||
public void PrepareForPacketHeader(int packetHeaderLength)
|
||||
{
|
||||
Reset(packetHeaderLength, null);
|
||||
}
|
||||
|
||||
public void PrepareForPacket(IPacketHeader packetHeader)
|
||||
{
|
||||
if (packetHeader == null)
|
||||
{
|
||||
throw new Exception("Packet header is invalid.");
|
||||
}
|
||||
|
||||
Reset(packetHeader.PacketLength, packetHeader);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (m_Disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
if (m_Stream != null)
|
||||
{
|
||||
m_Stream.Dispose();
|
||||
m_Stream = null;
|
||||
}
|
||||
}
|
||||
|
||||
m_Disposed = true;
|
||||
}
|
||||
|
||||
private void Reset(int targetLength, IPacketHeader packetHeader)
|
||||
{
|
||||
if (targetLength < 0)
|
||||
{
|
||||
throw new Exception("Target length is invalid.");
|
||||
}
|
||||
|
||||
m_Stream.Position = 0L;
|
||||
m_Stream.SetLength(targetLength);
|
||||
m_PacketHeader = packetHeader;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4a8a0b968c7b38442ae9bbf523e6f234
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,60 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
public sealed partial class NetworkManager
|
||||
{
|
||||
private sealed class SendState : IDisposable
|
||||
{
|
||||
private const int DefaultBufferLength = 1024 * 64;
|
||||
private MemoryStream m_Stream;
|
||||
private bool m_Disposed;
|
||||
|
||||
public SendState()
|
||||
{
|
||||
m_Stream = new MemoryStream(DefaultBufferLength);
|
||||
m_Disposed = false;
|
||||
}
|
||||
|
||||
public MemoryStream Stream
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Stream;
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
m_Stream.Position = 0L;
|
||||
m_Stream.SetLength(0L);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (m_Disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
if (m_Stream != null)
|
||||
{
|
||||
m_Stream.Dispose();
|
||||
m_Stream = null;
|
||||
}
|
||||
}
|
||||
|
||||
m_Disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01a1e8d0d67bac34a9d5ea40a96bb0eb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,350 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络管理器。
|
||||
/// </summary>
|
||||
public sealed partial class NetworkManager : INetworkManager
|
||||
{
|
||||
private readonly Dictionary<string, NetworkChannelBase> m_NetworkChannels;
|
||||
|
||||
private EventHandler<NetworkConnectedEventArgs> m_NetworkConnectedEventHandler;
|
||||
private EventHandler<NetworkClosedEventArgs> m_NetworkClosedEventHandler;
|
||||
private EventHandler<NetworkMissHeartBeatEventArgs> m_NetworkMissHeartBeatEventHandler;
|
||||
private EventHandler<NetworkErrorEventArgs> m_NetworkErrorEventHandler;
|
||||
private EventHandler<NetworkCustomErrorEventArgs> m_NetworkCustomErrorEventHandler;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化网络管理器的新实例。
|
||||
/// </summary>
|
||||
public NetworkManager()
|
||||
{
|
||||
m_NetworkChannels = new Dictionary<string, NetworkChannelBase>(StringComparer.Ordinal);
|
||||
m_NetworkConnectedEventHandler = null;
|
||||
m_NetworkClosedEventHandler = null;
|
||||
m_NetworkMissHeartBeatEventHandler = null;
|
||||
m_NetworkErrorEventHandler = null;
|
||||
m_NetworkCustomErrorEventHandler = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络频道数量。
|
||||
/// </summary>
|
||||
public int NetworkChannelCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_NetworkChannels.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 网络连接成功事件。
|
||||
/// </summary>
|
||||
public event EventHandler<NetworkConnectedEventArgs> NetworkConnected
|
||||
{
|
||||
add
|
||||
{
|
||||
m_NetworkConnectedEventHandler += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
m_NetworkConnectedEventHandler -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 网络连接关闭事件。
|
||||
/// </summary>
|
||||
public event EventHandler<NetworkClosedEventArgs> NetworkClosed
|
||||
{
|
||||
add
|
||||
{
|
||||
m_NetworkClosedEventHandler += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
m_NetworkClosedEventHandler -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 网络心跳包丢失事件。
|
||||
/// </summary>
|
||||
public event EventHandler<NetworkMissHeartBeatEventArgs> NetworkMissHeartBeat
|
||||
{
|
||||
add
|
||||
{
|
||||
m_NetworkMissHeartBeatEventHandler += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
m_NetworkMissHeartBeatEventHandler -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 网络错误事件。
|
||||
/// </summary>
|
||||
public event EventHandler<NetworkErrorEventArgs> NetworkError
|
||||
{
|
||||
add
|
||||
{
|
||||
m_NetworkErrorEventHandler += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
m_NetworkErrorEventHandler -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用户自定义网络错误事件。
|
||||
/// </summary>
|
||||
public event EventHandler<NetworkCustomErrorEventArgs> NetworkCustomError
|
||||
{
|
||||
add
|
||||
{
|
||||
m_NetworkCustomErrorEventHandler += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
m_NetworkCustomErrorEventHandler -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 网络管理器轮询。
|
||||
/// </summary>
|
||||
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
|
||||
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
|
||||
public void Update(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
foreach (KeyValuePair<string, NetworkChannelBase> networkChannel in m_NetworkChannels)
|
||||
{
|
||||
networkChannel.Value.Update(elapseSeconds, realElapseSeconds);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭并清理网络管理器。
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
foreach (KeyValuePair<string, NetworkChannelBase> networkChannel in m_NetworkChannels)
|
||||
{
|
||||
NetworkChannelBase networkChannelBase = networkChannel.Value;
|
||||
networkChannelBase.NetworkChannelConnected -= OnNetworkChannelConnected;
|
||||
networkChannelBase.NetworkChannelClosed -= OnNetworkChannelClosed;
|
||||
networkChannelBase.NetworkChannelMissHeartBeat -= OnNetworkChannelMissHeartBeat;
|
||||
networkChannelBase.NetworkChannelError -= OnNetworkChannelError;
|
||||
networkChannelBase.NetworkChannelCustomError -= OnNetworkChannelCustomError;
|
||||
networkChannelBase.Shutdown();
|
||||
}
|
||||
|
||||
m_NetworkChannels.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在网络频道。
|
||||
/// </summary>
|
||||
/// <param name="name">网络频道名称。</param>
|
||||
/// <returns>是否存在网络频道。</returns>
|
||||
public bool HasNetworkChannel(string name)
|
||||
{
|
||||
return m_NetworkChannels.ContainsKey(name ?? string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络频道。
|
||||
/// </summary>
|
||||
/// <param name="name">网络频道名称。</param>
|
||||
/// <returns>要获取的网络频道。</returns>
|
||||
public INetworkChannel GetNetworkChannel(string name)
|
||||
{
|
||||
NetworkChannelBase networkChannel = null;
|
||||
if (m_NetworkChannels.TryGetValue(name ?? string.Empty, out networkChannel))
|
||||
{
|
||||
return networkChannel;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有网络频道。
|
||||
/// </summary>
|
||||
/// <returns>所有网络频道。</returns>
|
||||
public INetworkChannel[] GetAllNetworkChannels()
|
||||
{
|
||||
int index = 0;
|
||||
INetworkChannel[] results = new INetworkChannel[m_NetworkChannels.Count];
|
||||
foreach (KeyValuePair<string, NetworkChannelBase> networkChannel in m_NetworkChannels)
|
||||
{
|
||||
results[index++] = networkChannel.Value;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有网络频道。
|
||||
/// </summary>
|
||||
/// <param name="results">所有网络频道。</param>
|
||||
public void GetAllNetworkChannels(List<INetworkChannel> results)
|
||||
{
|
||||
if (results == null)
|
||||
{
|
||||
throw new Exception("Results is invalid.");
|
||||
}
|
||||
|
||||
results.Clear();
|
||||
foreach (KeyValuePair<string, NetworkChannelBase> networkChannel in m_NetworkChannels)
|
||||
{
|
||||
results.Add(networkChannel.Value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建网络频道。
|
||||
/// </summary>
|
||||
/// <param name="name">网络频道名称。</param>
|
||||
/// <param name="serviceType">网络服务类型。</param>
|
||||
/// <param name="networkChannelHelper">网络频道辅助器。</param>
|
||||
/// <returns>要创建的网络频道。</returns>
|
||||
public INetworkChannel CreateNetworkChannel(string name, ServiceType serviceType, INetworkChannelHelper networkChannelHelper)
|
||||
{
|
||||
if (networkChannelHelper == null)
|
||||
{
|
||||
throw new Exception("Network channel helper is invalid.");
|
||||
}
|
||||
|
||||
if (networkChannelHelper.PacketHeaderLength < 0)
|
||||
{
|
||||
throw new Exception("Packet header length is invalid.");
|
||||
}
|
||||
|
||||
if (HasNetworkChannel(name))
|
||||
{
|
||||
throw new Exception(Utility.Text.Format("Already exist network channel '{0}'.", name ?? string.Empty));
|
||||
}
|
||||
|
||||
NetworkChannelBase networkChannel = null;
|
||||
switch (serviceType)
|
||||
{
|
||||
case ServiceType.Tcp:
|
||||
networkChannel = new TcpNetworkChannel(name, networkChannelHelper);
|
||||
break;
|
||||
|
||||
case ServiceType.TcpWithSyncReceive:
|
||||
networkChannel = new TcpWithSyncReceiveNetworkChannel(name, networkChannelHelper);
|
||||
break;
|
||||
|
||||
case ServiceType.Udp:
|
||||
networkChannel = new UdpNetworkChannel(name, networkChannelHelper);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception(Utility.Text.Format("Not supported service type '{0}'.", serviceType));
|
||||
}
|
||||
|
||||
networkChannel.NetworkChannelConnected += OnNetworkChannelConnected;
|
||||
networkChannel.NetworkChannelClosed += OnNetworkChannelClosed;
|
||||
networkChannel.NetworkChannelMissHeartBeat += OnNetworkChannelMissHeartBeat;
|
||||
networkChannel.NetworkChannelError += OnNetworkChannelError;
|
||||
networkChannel.NetworkChannelCustomError += OnNetworkChannelCustomError;
|
||||
m_NetworkChannels.Add(name, networkChannel);
|
||||
return networkChannel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁网络频道。
|
||||
/// </summary>
|
||||
/// <param name="name">网络频道名称。</param>
|
||||
/// <returns>是否销毁网络频道成功。</returns>
|
||||
public bool DestroyNetworkChannel(string name)
|
||||
{
|
||||
NetworkChannelBase networkChannel = null;
|
||||
if (m_NetworkChannels.TryGetValue(name ?? string.Empty, out networkChannel))
|
||||
{
|
||||
networkChannel.NetworkChannelConnected -= OnNetworkChannelConnected;
|
||||
networkChannel.NetworkChannelClosed -= OnNetworkChannelClosed;
|
||||
networkChannel.NetworkChannelMissHeartBeat -= OnNetworkChannelMissHeartBeat;
|
||||
networkChannel.NetworkChannelError -= OnNetworkChannelError;
|
||||
networkChannel.NetworkChannelCustomError -= OnNetworkChannelCustomError;
|
||||
networkChannel.Shutdown();
|
||||
return m_NetworkChannels.Remove(name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void OnNetworkChannelConnected(NetworkChannelBase networkChannel, object userData)
|
||||
{
|
||||
if (m_NetworkConnectedEventHandler != null)
|
||||
{
|
||||
lock (m_NetworkConnectedEventHandler)
|
||||
{
|
||||
NetworkConnectedEventArgs networkConnectedEventArgs = NetworkConnectedEventArgs.Create(networkChannel);
|
||||
m_NetworkConnectedEventHandler(this, networkConnectedEventArgs);
|
||||
MemoryPool.Release(networkConnectedEventArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnNetworkChannelClosed(NetworkChannelBase networkChannel)
|
||||
{
|
||||
if (m_NetworkClosedEventHandler != null)
|
||||
{
|
||||
lock (m_NetworkClosedEventHandler)
|
||||
{
|
||||
NetworkClosedEventArgs networkClosedEventArgs = NetworkClosedEventArgs.Create(networkChannel);
|
||||
m_NetworkClosedEventHandler(this, networkClosedEventArgs);
|
||||
MemoryPool.Release(networkClosedEventArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnNetworkChannelMissHeartBeat(NetworkChannelBase networkChannel, int missHeartBeatCount)
|
||||
{
|
||||
if (m_NetworkMissHeartBeatEventHandler != null)
|
||||
{
|
||||
lock (m_NetworkMissHeartBeatEventHandler)
|
||||
{
|
||||
NetworkMissHeartBeatEventArgs networkMissHeartBeatEventArgs = NetworkMissHeartBeatEventArgs.Create(networkChannel, missHeartBeatCount);
|
||||
m_NetworkMissHeartBeatEventHandler(this, networkMissHeartBeatEventArgs);
|
||||
MemoryPool.Release(networkMissHeartBeatEventArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnNetworkChannelError(NetworkChannelBase networkChannel, NetworkErrorCode errorCode, SocketError socketErrorCode, string errorMessage)
|
||||
{
|
||||
if (m_NetworkErrorEventHandler != null)
|
||||
{
|
||||
lock (m_NetworkErrorEventHandler)
|
||||
{
|
||||
NetworkErrorEventArgs networkErrorEventArgs = NetworkErrorEventArgs.Create(networkChannel, errorCode, socketErrorCode, errorMessage);
|
||||
m_NetworkErrorEventHandler(this, networkErrorEventArgs);
|
||||
MemoryPool.Release(networkErrorEventArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnNetworkChannelCustomError(NetworkChannelBase networkChannel, object customErrorData)
|
||||
{
|
||||
if (m_NetworkCustomErrorEventHandler != null)
|
||||
{
|
||||
lock (m_NetworkCustomErrorEventHandler)
|
||||
{
|
||||
NetworkCustomErrorEventArgs networkCustomErrorEventArgs = NetworkCustomErrorEventArgs.Create(networkChannel, customErrorData);
|
||||
m_NetworkCustomErrorEventHandler(this, networkCustomErrorEventArgs);
|
||||
MemoryPool.Release(networkCustomErrorEventArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ea28106108b496bb4b66fd8aa528797
|
||||
timeCreated: 1661772444
|
@@ -1,10 +0,0 @@
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络消息包基类。
|
||||
/// </summary>
|
||||
public abstract class Packet : BaseEventArgs
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4d54f03c4aed4afbab3b4fc45def97c5
|
||||
timeCreated: 1661771739
|
@@ -1,28 +0,0 @@
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络服务类型。
|
||||
/// </summary>
|
||||
public enum ServiceType : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// TCP 网络服务。
|
||||
/// </summary>
|
||||
Tcp = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 使用同步接收的 TCP 网络服务。
|
||||
/// </summary>
|
||||
TcpWithSyncReceive,
|
||||
|
||||
/// <summary>
|
||||
/// Udp 网络服务。
|
||||
/// </summary>
|
||||
Udp,
|
||||
|
||||
/// <summary>
|
||||
/// Kcp 网络服务。
|
||||
/// </summary>
|
||||
Kcp,
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 11929818b1dbde74ba521dc2c5d03f49
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bcf0e9cef581b5441ad604bfc2f771c4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,283 +0,0 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
public sealed partial class NetworkManager
|
||||
{
|
||||
/// <summary>
|
||||
/// TCP 网络频道。
|
||||
/// </summary>
|
||||
private sealed class TcpNetworkChannel : NetworkChannelBase
|
||||
{
|
||||
private readonly AsyncCallback m_ConnectCallback;
|
||||
private readonly AsyncCallback m_SendCallback;
|
||||
private readonly AsyncCallback m_ReceiveCallback;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化网络频道的新实例。
|
||||
/// </summary>
|
||||
/// <param name="name">网络频道名称。</param>
|
||||
/// <param name="networkChannelHelper">网络频道辅助器。</param>
|
||||
public TcpNetworkChannel(string name, INetworkChannelHelper networkChannelHelper)
|
||||
: base(name, networkChannelHelper)
|
||||
{
|
||||
m_ConnectCallback = ConnectCallback;
|
||||
m_SendCallback = SendCallback;
|
||||
m_ReceiveCallback = ReceiveCallback;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络服务类型。
|
||||
/// </summary>
|
||||
public override ServiceType ServiceType
|
||||
{
|
||||
get
|
||||
{
|
||||
return ServiceType.Tcp;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接到远程主机。
|
||||
/// </summary>
|
||||
/// <param name="ipAddress">远程主机的 IP 地址。</param>
|
||||
/// <param name="port">远程主机的端口号。</param>
|
||||
/// <param name="userData">用户自定义数据。</param>
|
||||
public override void Connect(IPAddress ipAddress, int port, object userData)
|
||||
{
|
||||
base.Connect(ipAddress, port, userData);
|
||||
m_Socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||
if (m_Socket == null)
|
||||
{
|
||||
string errorMessage = "Initialize network channel failure.";
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
NetworkChannelError(this, NetworkErrorCode.SocketError, SocketError.Success, errorMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Exception(errorMessage);
|
||||
}
|
||||
|
||||
m_NetworkChannelHelper.PrepareForConnecting();
|
||||
ConnectAsync(ipAddress, port, userData);
|
||||
}
|
||||
|
||||
protected override bool ProcessSend()
|
||||
{
|
||||
if (base.ProcessSend())
|
||||
{
|
||||
SendAsync();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void ConnectAsync(IPAddress ipAddress, int port, object userData)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_Socket.BeginConnect(ipAddress, port, m_ConnectCallback, new ConnectState(m_Socket, userData));
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
SocketException socketException = exception as SocketException;
|
||||
NetworkChannelError(this, NetworkErrorCode.ConnectError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void ConnectCallback(IAsyncResult ar)
|
||||
{
|
||||
ConnectState socketUserData = (ConnectState)ar.AsyncState;
|
||||
try
|
||||
{
|
||||
socketUserData.Socket.EndConnect(ar);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
m_Active = false;
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
SocketException socketException = exception as SocketException;
|
||||
NetworkChannelError(this, NetworkErrorCode.ConnectError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
m_SentPacketCount = 0;
|
||||
m_ReceivedPacketCount = 0;
|
||||
|
||||
lock (m_SendPacketPool)
|
||||
{
|
||||
m_SendPacketPool.Clear();
|
||||
}
|
||||
|
||||
m_ReceivePacketPool.Clear();
|
||||
|
||||
lock (m_HeartBeatState)
|
||||
{
|
||||
m_HeartBeatState.Reset(true);
|
||||
}
|
||||
|
||||
if (NetworkChannelConnected != null)
|
||||
{
|
||||
NetworkChannelConnected(this, socketUserData.UserData);
|
||||
}
|
||||
|
||||
m_Active = true;
|
||||
ReceiveAsync();
|
||||
}
|
||||
|
||||
private void SendAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_Socket.BeginSend(m_SendState.Stream.GetBuffer(), (int)m_SendState.Stream.Position, (int)(m_SendState.Stream.Length - m_SendState.Stream.Position), SocketFlags.None, m_SendCallback, m_Socket);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
m_Active = false;
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
SocketException socketException = exception as SocketException;
|
||||
NetworkChannelError(this, NetworkErrorCode.SendError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void SendCallback(IAsyncResult ar)
|
||||
{
|
||||
Socket socket = (Socket)ar.AsyncState;
|
||||
if (!socket.Connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int bytesSent = 0;
|
||||
try
|
||||
{
|
||||
bytesSent = socket.EndSend(ar);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
m_Active = false;
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
SocketException socketException = exception as SocketException;
|
||||
NetworkChannelError(this, NetworkErrorCode.SendError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
m_SendState.Stream.Position += bytesSent;
|
||||
if (m_SendState.Stream.Position < m_SendState.Stream.Length)
|
||||
{
|
||||
SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
m_SentPacketCount++;
|
||||
m_SendState.Reset();
|
||||
}
|
||||
|
||||
private void ReceiveAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_Socket.BeginReceive(m_ReceiveState.Stream.GetBuffer(), (int)m_ReceiveState.Stream.Position, (int)(m_ReceiveState.Stream.Length - m_ReceiveState.Stream.Position), SocketFlags.None, m_ReceiveCallback, m_Socket);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
m_Active = false;
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
SocketException socketException = exception as SocketException;
|
||||
NetworkChannelError(this, NetworkErrorCode.ReceiveError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void ReceiveCallback(IAsyncResult ar)
|
||||
{
|
||||
Socket socket = (Socket)ar.AsyncState;
|
||||
if (!socket.Connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int bytesReceived = 0;
|
||||
try
|
||||
{
|
||||
bytesReceived = socket.EndReceive(ar);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
m_Active = false;
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
SocketException socketException = exception as SocketException;
|
||||
NetworkChannelError(this, NetworkErrorCode.ReceiveError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
if (bytesReceived <= 0)
|
||||
{
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
||||
m_ReceiveState.Stream.Position += bytesReceived;
|
||||
if (m_ReceiveState.Stream.Position < m_ReceiveState.Stream.Length)
|
||||
{
|
||||
ReceiveAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
m_ReceiveState.Stream.Position = 0L;
|
||||
|
||||
bool processSuccess = false;
|
||||
if (m_ReceiveState.PacketHeader != null)
|
||||
{
|
||||
processSuccess = ProcessPacket();
|
||||
m_ReceivedPacketCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
processSuccess = ProcessPacketHeader();
|
||||
}
|
||||
|
||||
if (processSuccess)
|
||||
{
|
||||
ReceiveAsync();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2df585ebfe0562642b66664dbf0feaaf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,259 +0,0 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
public sealed partial class NetworkManager
|
||||
{
|
||||
/// <summary>
|
||||
/// 使用同步接收的 TCP 网络频道。
|
||||
/// </summary>
|
||||
private sealed class TcpWithSyncReceiveNetworkChannel : NetworkChannelBase
|
||||
{
|
||||
private readonly AsyncCallback m_ConnectCallback;
|
||||
private readonly AsyncCallback m_SendCallback;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化网络频道的新实例。
|
||||
/// </summary>
|
||||
/// <param name="name">网络频道名称。</param>
|
||||
/// <param name="networkChannelHelper">网络频道辅助器。</param>
|
||||
public TcpWithSyncReceiveNetworkChannel(string name, INetworkChannelHelper networkChannelHelper)
|
||||
: base(name, networkChannelHelper)
|
||||
{
|
||||
m_ConnectCallback = ConnectCallback;
|
||||
m_SendCallback = SendCallback;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络服务类型。
|
||||
/// </summary>
|
||||
public override ServiceType ServiceType
|
||||
{
|
||||
get
|
||||
{
|
||||
return ServiceType.TcpWithSyncReceive;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接到远程主机。
|
||||
/// </summary>
|
||||
/// <param name="ipAddress">远程主机的 IP 地址。</param>
|
||||
/// <param name="port">远程主机的端口号。</param>
|
||||
/// <param name="userData">用户自定义数据。</param>
|
||||
public override void Connect(IPAddress ipAddress, int port, object userData)
|
||||
{
|
||||
base.Connect(ipAddress, port, userData);
|
||||
m_Socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||
if (m_Socket == null)
|
||||
{
|
||||
string errorMessage = "Initialize network channel failure.";
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
NetworkChannelError(this, NetworkErrorCode.SocketError, SocketError.Success, errorMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Exception(errorMessage);
|
||||
}
|
||||
|
||||
m_NetworkChannelHelper.PrepareForConnecting();
|
||||
ConnectAsync(ipAddress, port, userData);
|
||||
}
|
||||
|
||||
protected override bool ProcessSend()
|
||||
{
|
||||
if (base.ProcessSend())
|
||||
{
|
||||
SendAsync();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override void ProcessReceive()
|
||||
{
|
||||
base.ProcessReceive();
|
||||
while (m_Socket.Available > 0)
|
||||
{
|
||||
if (!ReceiveSync())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ConnectAsync(IPAddress ipAddress, int port, object userData)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_Socket.BeginConnect(ipAddress, port, m_ConnectCallback, new ConnectState(m_Socket, userData));
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
SocketException socketException = exception as SocketException;
|
||||
NetworkChannelError(this, NetworkErrorCode.ConnectError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void ConnectCallback(IAsyncResult ar)
|
||||
{
|
||||
ConnectState socketUserData = (ConnectState)ar.AsyncState;
|
||||
try
|
||||
{
|
||||
socketUserData.Socket.EndConnect(ar);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
m_Active = false;
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
SocketException socketException = exception as SocketException;
|
||||
NetworkChannelError(this, NetworkErrorCode.ConnectError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
m_SentPacketCount = 0;
|
||||
m_ReceivedPacketCount = 0;
|
||||
|
||||
lock (m_SendPacketPool)
|
||||
{
|
||||
m_SendPacketPool.Clear();
|
||||
}
|
||||
|
||||
m_ReceivePacketPool.Clear();
|
||||
|
||||
lock (m_HeartBeatState)
|
||||
{
|
||||
m_HeartBeatState.Reset(true);
|
||||
}
|
||||
|
||||
if (NetworkChannelConnected != null)
|
||||
{
|
||||
NetworkChannelConnected(this, socketUserData.UserData);
|
||||
}
|
||||
|
||||
m_Active = true;
|
||||
}
|
||||
|
||||
private void SendAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_Socket.BeginSend(m_SendState.Stream.GetBuffer(), (int)m_SendState.Stream.Position, (int)(m_SendState.Stream.Length - m_SendState.Stream.Position), SocketFlags.None, m_SendCallback, m_Socket);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
m_Active = false;
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
SocketException socketException = exception as SocketException;
|
||||
NetworkChannelError(this, NetworkErrorCode.SendError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void SendCallback(IAsyncResult ar)
|
||||
{
|
||||
Socket socket = (Socket)ar.AsyncState;
|
||||
if (!socket.Connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int bytesSent = 0;
|
||||
try
|
||||
{
|
||||
bytesSent = socket.EndSend(ar);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
m_Active = false;
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
SocketException socketException = exception as SocketException;
|
||||
NetworkChannelError(this, NetworkErrorCode.SendError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
m_SendState.Stream.Position += bytesSent;
|
||||
if (m_SendState.Stream.Position < m_SendState.Stream.Length)
|
||||
{
|
||||
SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
m_SentPacketCount++;
|
||||
m_SendState.Reset();
|
||||
}
|
||||
|
||||
private bool ReceiveSync()
|
||||
{
|
||||
try
|
||||
{
|
||||
int bytesReceived = m_Socket.Receive(m_ReceiveState.Stream.GetBuffer(), (int)m_ReceiveState.Stream.Position, (int)(m_ReceiveState.Stream.Length - m_ReceiveState.Stream.Position), SocketFlags.None);
|
||||
if (bytesReceived <= 0)
|
||||
{
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_ReceiveState.Stream.Position += bytesReceived;
|
||||
if (m_ReceiveState.Stream.Position < m_ReceiveState.Stream.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_ReceiveState.Stream.Position = 0L;
|
||||
|
||||
bool processSuccess = false;
|
||||
if (m_ReceiveState.PacketHeader != null)
|
||||
{
|
||||
processSuccess = ProcessPacket();
|
||||
m_ReceivedPacketCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
processSuccess = ProcessPacketHeader();
|
||||
}
|
||||
|
||||
return processSuccess;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
m_Active = false;
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
SocketException socketException = exception as SocketException;
|
||||
NetworkChannelError(this, NetworkErrorCode.ReceiveError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19723c1417631894d90eef482924d87d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 181b125a26149ad4bbc6f270738f37ce
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,276 +0,0 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace TEngine.Runtime
|
||||
{
|
||||
|
||||
public sealed partial class NetworkManager
|
||||
{
|
||||
private sealed class UdpNetworkChannel : NetworkChannelBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取网络服务类型。
|
||||
/// </summary>
|
||||
public override ServiceType ServiceType => ServiceType.Udp;
|
||||
|
||||
|
||||
private readonly AsyncCallback m_ConnectCallback;
|
||||
private readonly AsyncCallback m_SendCallback;
|
||||
private readonly AsyncCallback m_ReceiveCallback;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化网络频道的新实例。
|
||||
/// </summary>
|
||||
/// <param name="name">网络频道名称。</param>
|
||||
/// <param name="networkChannelHelper">网络频道辅助器。</param>
|
||||
public UdpNetworkChannel(string name, INetworkChannelHelper networkChannelHelper)
|
||||
: base(name, networkChannelHelper)
|
||||
{
|
||||
m_ConnectCallback = ConnectCallback;
|
||||
m_SendCallback = SendCallback;
|
||||
m_ReceiveCallback = ReceiveCallback;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接到远程主机。
|
||||
/// </summary>
|
||||
/// <param name="ipAddress">远程主机的 IP 地址。</param>
|
||||
/// <param name="port">远程主机的端口号。</param>
|
||||
/// <param name="userData">用户自定义数据。</param>
|
||||
public override void Connect(IPAddress ipAddress, int port, object userData)
|
||||
{
|
||||
base.Connect(ipAddress, port, userData);
|
||||
m_Socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Udp);
|
||||
if (m_Socket == null)
|
||||
{
|
||||
string errorMessage = "Initialize network channel failure.";
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
NetworkChannelError(this, NetworkErrorCode.SocketError, SocketError.Success, errorMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Exception(errorMessage);
|
||||
}
|
||||
|
||||
m_NetworkChannelHelper.PrepareForConnecting();
|
||||
ConnectAsync(ipAddress, port, userData);
|
||||
}
|
||||
|
||||
protected override bool ProcessSend()
|
||||
{
|
||||
if (base.ProcessSend())
|
||||
{
|
||||
SendAsync();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void ConnectAsync(IPAddress ipAddress, int port, object userData)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_Socket.BeginConnect(ipAddress, port, m_ConnectCallback, new ConnectState(m_Socket, userData));
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
SocketException socketException = exception as SocketException;
|
||||
NetworkChannelError(this, NetworkErrorCode.ConnectError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void ConnectCallback(IAsyncResult ar)
|
||||
{
|
||||
ConnectState socketUserData = (ConnectState)ar.AsyncState;
|
||||
try
|
||||
{
|
||||
socketUserData.Socket.EndConnect(ar);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
m_Active = false;
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
SocketException socketException = exception as SocketException;
|
||||
NetworkChannelError(this, NetworkErrorCode.ConnectError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
m_SentPacketCount = 0;
|
||||
m_ReceivedPacketCount = 0;
|
||||
|
||||
lock (m_SendPacketPool)
|
||||
{
|
||||
m_SendPacketPool.Clear();
|
||||
}
|
||||
|
||||
m_ReceivePacketPool.Clear();
|
||||
|
||||
lock (m_HeartBeatState)
|
||||
{
|
||||
m_HeartBeatState.Reset(true);
|
||||
}
|
||||
|
||||
if (NetworkChannelConnected != null)
|
||||
{
|
||||
NetworkChannelConnected(this, socketUserData.UserData);
|
||||
}
|
||||
|
||||
m_Active = true;
|
||||
ReceiveAsync();
|
||||
}
|
||||
|
||||
private void SendAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_Socket.BeginSend(m_SendState.Stream.GetBuffer(), (int)m_SendState.Stream.Position, (int)(m_SendState.Stream.Length - m_SendState.Stream.Position), SocketFlags.None, m_SendCallback, m_Socket);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
m_Active = false;
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
SocketException socketException = exception as SocketException;
|
||||
NetworkChannelError(this, NetworkErrorCode.SendError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void SendCallback(IAsyncResult ar)
|
||||
{
|
||||
Socket socket = (Socket)ar.AsyncState;
|
||||
if (!socket.Connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int bytesSent = 0;
|
||||
try
|
||||
{
|
||||
bytesSent = socket.EndSend(ar);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
m_Active = false;
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
SocketException socketException = exception as SocketException;
|
||||
NetworkChannelError(this, NetworkErrorCode.SendError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
m_SendState.Stream.Position += bytesSent;
|
||||
if (m_SendState.Stream.Position < m_SendState.Stream.Length)
|
||||
{
|
||||
SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
m_SentPacketCount++;
|
||||
m_SendState.Reset();
|
||||
}
|
||||
|
||||
private void ReceiveAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_Socket.BeginReceive(m_ReceiveState.Stream.GetBuffer(), (int)m_ReceiveState.Stream.Position, (int)(m_ReceiveState.Stream.Length - m_ReceiveState.Stream.Position), SocketFlags.None, m_ReceiveCallback, m_Socket);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
m_Active = false;
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
SocketException socketException = exception as SocketException;
|
||||
NetworkChannelError(this, NetworkErrorCode.ReceiveError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void ReceiveCallback(IAsyncResult ar)
|
||||
{
|
||||
Socket socket = (Socket)ar.AsyncState;
|
||||
if (!socket.Connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int bytesReceived = 0;
|
||||
try
|
||||
{
|
||||
bytesReceived = socket.EndReceive(ar);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
m_Active = false;
|
||||
if (NetworkChannelError != null)
|
||||
{
|
||||
SocketException socketException = exception as SocketException;
|
||||
NetworkChannelError(this, NetworkErrorCode.ReceiveError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
if (bytesReceived <= 0)
|
||||
{
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
||||
m_ReceiveState.Stream.Position += bytesReceived;
|
||||
if (m_ReceiveState.Stream.Position < m_ReceiveState.Stream.Length)
|
||||
{
|
||||
ReceiveAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
m_ReceiveState.Stream.Position = 0L;
|
||||
|
||||
bool processSuccess = false;
|
||||
if (m_ReceiveState.PacketHeader != null)
|
||||
{
|
||||
processSuccess = ProcessPacket();
|
||||
m_ReceivedPacketCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
processSuccess = ProcessPacketHeader();
|
||||
}
|
||||
|
||||
if (processSuccess)
|
||||
{
|
||||
ReceiveAsync();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17b9e06584f10da45a8a3ca27fd5e654
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user