mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 11:00:32 +00:00
465 lines
15 KiB
C#
465 lines
15 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
using UnityEngine.Networking.Types;
|
|
using System.Collections.ObjectModel;
|
|
|
|
#if ENABLE_UNET
|
|
|
|
namespace UnityEngine.Networking
|
|
{
|
|
public class NetworkServerSimple
|
|
{
|
|
bool m_Initialized = false;
|
|
int m_ListenPort;
|
|
int m_ServerHostId = -1;
|
|
int m_RelaySlotId = -1;
|
|
bool m_UseWebSockets;
|
|
|
|
byte[] m_MsgBuffer = null;
|
|
NetworkReader m_MsgReader = null;
|
|
|
|
Type m_NetworkConnectionClass = typeof(NetworkConnection);
|
|
HostTopology m_HostTopology;
|
|
List<NetworkConnection> m_Connections = new List<NetworkConnection>();
|
|
ReadOnlyCollection<NetworkConnection> m_ConnectionsReadOnly;
|
|
|
|
NetworkMessageHandlers m_MessageHandlers = new NetworkMessageHandlers();
|
|
|
|
public int listenPort { get { return m_ListenPort; } set { m_ListenPort = value; }}
|
|
public int serverHostId { get { return m_ServerHostId; } set { m_ServerHostId = value; }}
|
|
public HostTopology hostTopology { get { return m_HostTopology; }}
|
|
public bool useWebSockets { get { return m_UseWebSockets; } set { m_UseWebSockets = value; } }
|
|
public ReadOnlyCollection<NetworkConnection> connections { get { return m_ConnectionsReadOnly; }}
|
|
public Dictionary<short, NetworkMessageDelegate> handlers { get { return m_MessageHandlers.GetHandlers(); } }
|
|
|
|
public byte[] messageBuffer { get { return m_MsgBuffer; }}
|
|
public NetworkReader messageReader { get { return m_MsgReader; }}
|
|
|
|
public Type networkConnectionClass
|
|
{
|
|
get { return m_NetworkConnectionClass; }
|
|
}
|
|
|
|
public void SetNetworkConnectionClass<T>() where T : NetworkConnection
|
|
{
|
|
m_NetworkConnectionClass = typeof(T);
|
|
}
|
|
|
|
public NetworkServerSimple()
|
|
{
|
|
m_ConnectionsReadOnly = new ReadOnlyCollection<NetworkConnection>(m_Connections);
|
|
}
|
|
|
|
public virtual void Initialize()
|
|
{
|
|
if (m_Initialized)
|
|
return;
|
|
|
|
m_Initialized = true;
|
|
NetworkTransport.Init();
|
|
|
|
m_MsgBuffer = new byte[NetworkMessage.MaxMessageSize];
|
|
m_MsgReader = new NetworkReader(m_MsgBuffer);
|
|
|
|
if (m_HostTopology == null)
|
|
{
|
|
var config = new ConnectionConfig();
|
|
config.AddChannel(QosType.ReliableSequenced);
|
|
config.AddChannel(QosType.Unreliable);
|
|
m_HostTopology = new HostTopology(config, 8);
|
|
}
|
|
|
|
if (LogFilter.logDebug) { Debug.Log("NetworkServerSimple initialize."); }
|
|
}
|
|
|
|
public bool Configure(ConnectionConfig config, int maxConnections)
|
|
{
|
|
HostTopology top = new HostTopology(config, maxConnections);
|
|
return Configure(top);
|
|
}
|
|
|
|
public bool Configure(HostTopology topology)
|
|
{
|
|
m_HostTopology = topology;
|
|
return true;
|
|
}
|
|
|
|
public bool Listen(string ipAddress, int serverListenPort)
|
|
{
|
|
Initialize();
|
|
m_ListenPort = serverListenPort;
|
|
|
|
if (m_UseWebSockets)
|
|
{
|
|
m_ServerHostId = NetworkTransport.AddWebsocketHost(m_HostTopology, serverListenPort, ipAddress);
|
|
}
|
|
else
|
|
{
|
|
m_ServerHostId = NetworkTransport.AddHost(m_HostTopology, serverListenPort, ipAddress);
|
|
}
|
|
|
|
if (m_ServerHostId == -1)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (LogFilter.logDebug) { Debug.Log("NetworkServerSimple listen: " + ipAddress + ":" + m_ListenPort); }
|
|
return true;
|
|
}
|
|
|
|
public bool Listen(int serverListenPort)
|
|
{
|
|
return Listen(serverListenPort, m_HostTopology);
|
|
}
|
|
|
|
public bool Listen(int serverListenPort, HostTopology topology)
|
|
{
|
|
m_HostTopology = topology;
|
|
Initialize();
|
|
m_ListenPort = serverListenPort;
|
|
|
|
if (m_UseWebSockets)
|
|
{
|
|
m_ServerHostId = NetworkTransport.AddWebsocketHost(m_HostTopology, serverListenPort);
|
|
}
|
|
else
|
|
{
|
|
m_ServerHostId = NetworkTransport.AddHost(m_HostTopology, serverListenPort);
|
|
}
|
|
|
|
if (m_ServerHostId == -1)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (LogFilter.logDebug) { Debug.Log("NetworkServerSimple listen " + m_ListenPort); }
|
|
return true;
|
|
}
|
|
|
|
public void ListenRelay(string relayIp, int relayPort, NetworkID netGuid, SourceID sourceId, NodeID nodeId)
|
|
{
|
|
Initialize();
|
|
|
|
m_ServerHostId = NetworkTransport.AddHost(m_HostTopology, listenPort);
|
|
if (LogFilter.logDebug) { Debug.Log("Server Host Slot Id: " + m_ServerHostId); }
|
|
|
|
Update();
|
|
|
|
byte error;
|
|
NetworkTransport.ConnectAsNetworkHost(
|
|
m_ServerHostId,
|
|
relayIp,
|
|
relayPort,
|
|
netGuid,
|
|
sourceId,
|
|
nodeId,
|
|
out error);
|
|
|
|
m_RelaySlotId = 0;
|
|
if (LogFilter.logDebug) { Debug.Log("Relay Slot Id: " + m_RelaySlotId); }
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
if (LogFilter.logDebug) { Debug.Log("NetworkServerSimple stop "); }
|
|
NetworkTransport.RemoveHost(m_ServerHostId);
|
|
m_ServerHostId = -1;
|
|
}
|
|
|
|
internal void RegisterHandlerSafe(short msgType, NetworkMessageDelegate handler)
|
|
{
|
|
m_MessageHandlers.RegisterHandlerSafe(msgType, handler);
|
|
}
|
|
|
|
public void RegisterHandler(short msgType, NetworkMessageDelegate handler)
|
|
{
|
|
m_MessageHandlers.RegisterHandler(msgType, handler);
|
|
}
|
|
|
|
public void UnregisterHandler(short msgType)
|
|
{
|
|
m_MessageHandlers.UnregisterHandler(msgType);
|
|
}
|
|
|
|
public void ClearHandlers()
|
|
{
|
|
m_MessageHandlers.ClearMessageHandlers();
|
|
}
|
|
|
|
// this can be used independantly of Update() - such as when using external connections and not listening.
|
|
public void UpdateConnections()
|
|
{
|
|
for (int i = 0; i < m_Connections.Count; i++)
|
|
{
|
|
NetworkConnection conn = m_Connections[i];
|
|
if (conn != null)
|
|
conn.FlushChannels();
|
|
}
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
if (m_ServerHostId == -1)
|
|
return;
|
|
|
|
int connectionId;
|
|
int channelId;
|
|
int receivedSize;
|
|
byte error;
|
|
|
|
var networkEvent = NetworkEventType.DataEvent;
|
|
if (m_RelaySlotId != -1)
|
|
{
|
|
networkEvent = NetworkTransport.ReceiveRelayEventFromHost(m_ServerHostId, out error);
|
|
if (NetworkEventType.Nothing != networkEvent)
|
|
{
|
|
if (LogFilter.logDebug) { Debug.Log("NetGroup event:" + networkEvent); }
|
|
}
|
|
if (networkEvent == NetworkEventType.ConnectEvent)
|
|
{
|
|
if (LogFilter.logDebug) { Debug.Log("NetGroup server connected"); }
|
|
}
|
|
if (networkEvent == NetworkEventType.DisconnectEvent)
|
|
{
|
|
if (LogFilter.logDebug) { Debug.Log("NetGroup server disconnected"); }
|
|
}
|
|
}
|
|
|
|
do
|
|
{
|
|
networkEvent = NetworkTransport.ReceiveFromHost(m_ServerHostId, out connectionId, out channelId, m_MsgBuffer, (int)m_MsgBuffer.Length, out receivedSize, out error);
|
|
if (networkEvent != NetworkEventType.Nothing)
|
|
{
|
|
if (LogFilter.logDev) { Debug.Log("Server event: host=" + m_ServerHostId + " event=" + networkEvent + " error=" + error); }
|
|
}
|
|
|
|
switch (networkEvent)
|
|
{
|
|
case NetworkEventType.ConnectEvent:
|
|
{
|
|
HandleConnect(connectionId, error);
|
|
break;
|
|
}
|
|
|
|
case NetworkEventType.DataEvent:
|
|
{
|
|
HandleData(connectionId, channelId, receivedSize, error);
|
|
break;
|
|
}
|
|
|
|
case NetworkEventType.DisconnectEvent:
|
|
{
|
|
HandleDisconnect(connectionId, error);
|
|
break;
|
|
}
|
|
|
|
case NetworkEventType.Nothing:
|
|
break;
|
|
|
|
default:
|
|
if (LogFilter.logError) { Debug.LogError("Unknown network message type received: " + networkEvent); }
|
|
break;
|
|
}
|
|
}
|
|
while (networkEvent != NetworkEventType.Nothing);
|
|
|
|
UpdateConnections();
|
|
}
|
|
|
|
public NetworkConnection FindConnection(int connectionId)
|
|
{
|
|
if (connectionId < 0 || connectionId >= m_Connections.Count)
|
|
return null;
|
|
|
|
return m_Connections[connectionId];
|
|
}
|
|
|
|
public bool SetConnectionAtIndex(NetworkConnection conn)
|
|
{
|
|
while (m_Connections.Count <= conn.connectionId)
|
|
{
|
|
m_Connections.Add(null);
|
|
}
|
|
|
|
if (m_Connections[conn.connectionId] != null)
|
|
{
|
|
// already a connection at this index
|
|
return false;
|
|
}
|
|
|
|
m_Connections[conn.connectionId] = conn;
|
|
conn.SetHandlers(m_MessageHandlers);
|
|
return true;
|
|
}
|
|
|
|
public bool RemoveConnectionAtIndex(int connectionId)
|
|
{
|
|
if (connectionId < 0 || connectionId >= m_Connections.Count)
|
|
return false;
|
|
|
|
m_Connections[connectionId] = null;
|
|
return true;
|
|
}
|
|
|
|
void HandleConnect(int connectionId, byte error)
|
|
{
|
|
if (LogFilter.logDebug) { Debug.Log("NetworkServerSimple accepted client:" + connectionId); }
|
|
|
|
if (error != 0)
|
|
{
|
|
OnConnectError(connectionId, error);
|
|
return;
|
|
}
|
|
|
|
string address;
|
|
int port;
|
|
NetworkID networkId;
|
|
NodeID node;
|
|
byte error2;
|
|
NetworkTransport.GetConnectionInfo(m_ServerHostId, connectionId, out address, out port, out networkId, out node, out error2);
|
|
|
|
NetworkConnection conn = (NetworkConnection)Activator.CreateInstance(m_NetworkConnectionClass);
|
|
conn.SetHandlers(m_MessageHandlers);
|
|
conn.Initialize(address, m_ServerHostId, connectionId, m_HostTopology);
|
|
conn.lastError = (NetworkError)error2;
|
|
|
|
// add connection at correct index
|
|
while (m_Connections.Count <= connectionId)
|
|
{
|
|
m_Connections.Add(null);
|
|
}
|
|
m_Connections[connectionId] = conn;
|
|
|
|
OnConnected(conn);
|
|
}
|
|
|
|
void HandleDisconnect(int connectionId, byte error)
|
|
{
|
|
if (LogFilter.logDebug) { Debug.Log("NetworkServerSimple disconnect client:" + connectionId); }
|
|
|
|
var conn = FindConnection(connectionId);
|
|
if (conn == null)
|
|
{
|
|
return;
|
|
}
|
|
conn.lastError = (NetworkError)error;
|
|
|
|
if (error != 0)
|
|
{
|
|
if ((NetworkError)error != NetworkError.Timeout)
|
|
{
|
|
m_Connections[connectionId] = null;
|
|
if (LogFilter.logError) { Debug.LogError("Server client disconnect error, connectionId: " + connectionId + " error: " + (NetworkError)error); }
|
|
|
|
OnDisconnectError(conn, error);
|
|
return;
|
|
}
|
|
}
|
|
|
|
conn.Disconnect();
|
|
m_Connections[connectionId] = null;
|
|
if (LogFilter.logDebug) { Debug.Log("Server lost client:" + connectionId); }
|
|
|
|
OnDisconnected(conn);
|
|
}
|
|
|
|
void HandleData(int connectionId, int channelId, int receivedSize, byte error)
|
|
{
|
|
var conn = FindConnection(connectionId);
|
|
if (conn == null)
|
|
{
|
|
if (LogFilter.logError) { Debug.LogError("HandleData Unknown connectionId:" + connectionId); }
|
|
return;
|
|
}
|
|
conn.lastError = (NetworkError)error;
|
|
|
|
if (error != 0)
|
|
{
|
|
OnDataError(conn, error);
|
|
return;
|
|
}
|
|
|
|
m_MsgReader.SeekZero();
|
|
OnData(conn, receivedSize, channelId);
|
|
}
|
|
|
|
public void SendBytesTo(int connectionId, byte[] bytes, int numBytes, int channelId)
|
|
{
|
|
var outConn = FindConnection(connectionId);
|
|
if (outConn == null)
|
|
{
|
|
return;
|
|
}
|
|
outConn.SendBytes(bytes, numBytes, channelId);
|
|
}
|
|
|
|
public void SendWriterTo(int connectionId, NetworkWriter writer, int channelId)
|
|
{
|
|
var outConn = FindConnection(connectionId);
|
|
if (outConn == null)
|
|
{
|
|
return;
|
|
}
|
|
outConn.SendWriter(writer, channelId);
|
|
}
|
|
|
|
public void Disconnect(int connectionId)
|
|
{
|
|
var outConn = FindConnection(connectionId);
|
|
if (outConn == null)
|
|
{
|
|
return;
|
|
}
|
|
outConn.Disconnect();
|
|
m_Connections[connectionId] = null;
|
|
}
|
|
|
|
public void DisconnectAllConnections()
|
|
{
|
|
for (int i = 0; i < m_Connections.Count; i++)
|
|
{
|
|
NetworkConnection conn = m_Connections[i];
|
|
if (conn != null)
|
|
{
|
|
conn.Disconnect();
|
|
conn.Dispose();
|
|
}
|
|
}
|
|
}
|
|
|
|
// --------------------------- virtuals ---------------------------------------
|
|
|
|
public virtual void OnConnectError(int connectionId, byte error)
|
|
{
|
|
Debug.LogError("OnConnectError error:" + error);
|
|
}
|
|
|
|
public virtual void OnDataError(NetworkConnection conn, byte error)
|
|
{
|
|
Debug.LogError("OnDataError error:" + error);
|
|
}
|
|
|
|
public virtual void OnDisconnectError(NetworkConnection conn, byte error)
|
|
{
|
|
Debug.LogError("OnDisconnectError error:" + error);
|
|
}
|
|
|
|
public virtual void OnConnected(NetworkConnection conn)
|
|
{
|
|
conn.InvokeHandlerNoData(MsgType.Connect);
|
|
}
|
|
|
|
public virtual void OnDisconnected(NetworkConnection conn)
|
|
{
|
|
conn.InvokeHandlerNoData(MsgType.Disconnect);
|
|
}
|
|
|
|
public virtual void OnData(NetworkConnection conn, int receivedSize, int channelId)
|
|
{
|
|
conn.TransportReceive(m_MsgBuffer, receivedSize, channelId);
|
|
}
|
|
}
|
|
}
|
|
#endif
|