//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Net.Sockets;
namespace GameFramework.Network
{
///
/// 网络管理器。
///
internal sealed partial class NetworkManager : GameFrameworkModule, INetworkManager
{
private readonly Dictionary m_NetworkChannels;
private EventHandler m_NetworkConnectedEventHandler;
private EventHandler m_NetworkClosedEventHandler;
private EventHandler m_NetworkMissHeartBeatEventHandler;
private EventHandler m_NetworkErrorEventHandler;
private EventHandler m_NetworkCustomErrorEventHandler;
///
/// 初始化网络管理器的新实例。
///
public NetworkManager()
{
m_NetworkChannels = new Dictionary(StringComparer.Ordinal);
m_NetworkConnectedEventHandler = null;
m_NetworkClosedEventHandler = null;
m_NetworkMissHeartBeatEventHandler = null;
m_NetworkErrorEventHandler = null;
m_NetworkCustomErrorEventHandler = null;
}
///
/// 获取网络频道数量。
///
public int NetworkChannelCount
{
get
{
return m_NetworkChannels.Count;
}
}
///
/// 网络连接成功事件。
///
public event EventHandler NetworkConnected
{
add
{
m_NetworkConnectedEventHandler += value;
}
remove
{
m_NetworkConnectedEventHandler -= value;
}
}
///
/// 网络连接关闭事件。
///
public event EventHandler NetworkClosed
{
add
{
m_NetworkClosedEventHandler += value;
}
remove
{
m_NetworkClosedEventHandler -= value;
}
}
///
/// 网络心跳包丢失事件。
///
public event EventHandler NetworkMissHeartBeat
{
add
{
m_NetworkMissHeartBeatEventHandler += value;
}
remove
{
m_NetworkMissHeartBeatEventHandler -= value;
}
}
///
/// 网络错误事件。
///
public event EventHandler NetworkError
{
add
{
m_NetworkErrorEventHandler += value;
}
remove
{
m_NetworkErrorEventHandler -= value;
}
}
///
/// 用户自定义网络错误事件。
///
public event EventHandler NetworkCustomError
{
add
{
m_NetworkCustomErrorEventHandler += value;
}
remove
{
m_NetworkCustomErrorEventHandler -= value;
}
}
///
/// 网络管理器轮询。
///
/// 逻辑流逝时间,以秒为单位。
/// 真实流逝时间,以秒为单位。
internal override void Update(float elapseSeconds, float realElapseSeconds)
{
foreach (KeyValuePair networkChannel in m_NetworkChannels)
{
networkChannel.Value.Update(elapseSeconds, realElapseSeconds);
}
}
///
/// 关闭并清理网络管理器。
///
internal override void Shutdown()
{
foreach (KeyValuePair 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();
}
///
/// 检查是否存在网络频道。
///
/// 网络频道名称。
/// 是否存在网络频道。
public bool HasNetworkChannel(string name)
{
return m_NetworkChannels.ContainsKey(name ?? string.Empty);
}
///
/// 获取网络频道。
///
/// 网络频道名称。
/// 要获取的网络频道。
public INetworkChannel GetNetworkChannel(string name)
{
NetworkChannelBase networkChannel = null;
if (m_NetworkChannels.TryGetValue(name ?? string.Empty, out networkChannel))
{
return networkChannel;
}
return null;
}
///
/// 获取所有网络频道。
///
/// 所有网络频道。
public INetworkChannel[] GetAllNetworkChannels()
{
int index = 0;
INetworkChannel[] results = new INetworkChannel[m_NetworkChannels.Count];
foreach (KeyValuePair networkChannel in m_NetworkChannels)
{
results[index++] = networkChannel.Value;
}
return results;
}
///
/// 获取所有网络频道。
///
/// 所有网络频道。
public void GetAllNetworkChannels(List results)
{
if (results == null)
{
throw new GameFrameworkException("Results is invalid.");
}
results.Clear();
foreach (KeyValuePair networkChannel in m_NetworkChannels)
{
results.Add(networkChannel.Value);
}
}
///
/// 创建网络频道。
///
/// 网络频道名称。
/// 网络服务类型。
/// 网络频道辅助器。
/// 要创建的网络频道。
public INetworkChannel CreateNetworkChannel(string name, ServiceType serviceType, INetworkChannelHelper networkChannelHelper)
{
if (networkChannelHelper == null)
{
throw new GameFrameworkException("Network channel helper is invalid.");
}
if (networkChannelHelper.PacketHeaderLength < 0)
{
throw new GameFrameworkException("Packet header length is invalid.");
}
if (HasNetworkChannel(name))
{
throw new GameFrameworkException(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;
default:
throw new GameFrameworkException(Utility.Text.Format("Not supported service type '{0}'.", serviceType.ToString()));
}
networkChannel.NetworkChannelConnected += OnNetworkChannelConnected;
networkChannel.NetworkChannelClosed += OnNetworkChannelClosed;
networkChannel.NetworkChannelMissHeartBeat += OnNetworkChannelMissHeartBeat;
networkChannel.NetworkChannelError += OnNetworkChannelError;
networkChannel.NetworkChannelCustomError += OnNetworkChannelCustomError;
m_NetworkChannels.Add(name, networkChannel);
return networkChannel;
}
///
/// 销毁网络频道。
///
/// 网络频道名称。
/// 是否销毁网络频道成功。
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, userData);
m_NetworkConnectedEventHandler(this, networkConnectedEventArgs);
ReferencePool.Release(networkConnectedEventArgs);
}
}
}
private void OnNetworkChannelClosed(NetworkChannelBase networkChannel)
{
if (m_NetworkClosedEventHandler != null)
{
lock (m_NetworkClosedEventHandler)
{
NetworkClosedEventArgs networkClosedEventArgs = NetworkClosedEventArgs.Create(networkChannel);
m_NetworkClosedEventHandler(this, networkClosedEventArgs);
ReferencePool.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);
ReferencePool.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);
ReferencePool.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);
ReferencePool.Release(networkCustomErrorEventArgs);
}
}
}
}
}