ServerBehaviour.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. using UnityEngine;
  2. using UnityEngine.Assertions;
  3. using Unity.Collections;
  4. using Unity.Networking.Transport;
  5. using KairoEngine.Core;
  6. namespace KairoEngine.Multiplayer
  7. {
  8. public class ServerBehaviour : MonoBehaviour
  9. {
  10. public ushort port = 9000;
  11. public int players = 4;
  12. public bool autoStart = true;
  13. public string eventStreamName = "ServerEvents";
  14. public bool debug = false;
  15. public NetworkDriver m_Driver;
  16. public NativeList<NetworkConnection> m_Connections;
  17. private bool locked = false;
  18. void Start ()
  19. {
  20. if(autoStart) StartServer();
  21. }
  22. public void StartServer()
  23. {
  24. if(locked) return;
  25. m_Driver = NetworkDriver.Create();
  26. var endpoint = NetworkEndPoint.AnyIpv4;
  27. endpoint.Port = port;
  28. if (m_Driver.Bind(endpoint) != 0)
  29. {
  30. if(debug) Debug.Log($"Failed to bind to port {port}");
  31. GenericEvents.Trigger($"{eventStreamName}_PortError", $"Failed to bind to port {port}");
  32. }
  33. else
  34. {
  35. m_Driver.Listen();
  36. if(debug) Debug.Log($"Server listening on port {port}");
  37. GenericEvents.Trigger($"{eventStreamName}_Listening", $"Server listening on port {port}");
  38. locked = true;
  39. }
  40. m_Connections = new NativeList<NetworkConnection>(players, Allocator.Persistent);
  41. }
  42. public void StopServer()
  43. {
  44. NetDisconnectMsg netDisconnectMsg = new NetDisconnectMsg();
  45. SendNetMsgToAllClients((uint)NetOpCode.Disconnect, netDisconnectMsg);
  46. Timer.ExecuteRealTime(500, () => {
  47. if(debug) Debug.Log($"Server has stopped");
  48. GenericEvents.Trigger($"{eventStreamName}_Stopped", $"Server has stopped");
  49. m_Driver.Dispose();
  50. m_Connections.Dispose();
  51. locked = false;
  52. });
  53. }
  54. public void SendNetMsgToClient(int id, uint code, NetMsg netMsg)
  55. {
  56. DataStreamWriter writer = new DataStreamWriter();
  57. m_Driver.BeginSend(m_Connections[id], out writer);
  58. NetMsgController.Serialize(code, netMsg, ref writer, this, id);
  59. m_Driver.EndSend(writer);
  60. }
  61. public void SendNetMsgToAllClients(uint code, NetMsg netMsg)
  62. {
  63. for (int i = 0; i < m_Connections.Length; i++)
  64. {
  65. Assert.IsTrue(m_Connections[i].IsCreated);
  66. SendNetMsgToClient(i, code, netMsg);
  67. }
  68. }
  69. public void OnDestroy()
  70. {
  71. if(!m_Driver.IsCreated) return;
  72. m_Driver.Dispose();
  73. m_Connections.Dispose();
  74. }
  75. void Update ()
  76. {
  77. if(!m_Driver.IsCreated) return;
  78. m_Driver.ScheduleUpdate().Complete();
  79. // CleanUpConnections
  80. for (int i = 0; i < m_Connections.Length; i++)
  81. {
  82. if (!m_Connections[i].IsCreated)
  83. {
  84. m_Connections.RemoveAtSwapBack(i);
  85. --i;
  86. }
  87. }
  88. // AcceptNewConnections
  89. NetworkConnection c;
  90. while ((c = m_Driver.Accept()) != default(NetworkConnection))
  91. {
  92. m_Connections.Add(c);
  93. if(debug) Debug.Log($"Accepted a connection (ID {c.InternalId})");
  94. GenericEvents.Trigger($"{eventStreamName}_ClientConnected", $"Accepted a connection (ID {c.InternalId})", c.InternalId);
  95. }
  96. DataStreamReader stream;
  97. for (int i = 0; i < m_Connections.Length; i++)
  98. {
  99. Assert.IsTrue(m_Connections[i].IsCreated);
  100. NetworkEvent.Type cmd;
  101. while ((cmd = m_Driver.PopEventForConnection(m_Connections[i], out stream)) != NetworkEvent.Type.Empty)
  102. {
  103. if (cmd == NetworkEvent.Type.Data)
  104. {
  105. //if(debug) Debug.Log("Server received data from client");
  106. uint code = stream.ReadByte();
  107. NetMsgController.Deserialize(code, ref stream, this, i);
  108. }
  109. else if (cmd == NetworkEvent.Type.Disconnect)
  110. {
  111. if(debug) Debug.Log($"Client disconnected from server (ID {m_Connections[i].InternalId})");
  112. GenericEvents.Trigger($"{eventStreamName}_ClientDisconnected", $"Client disconnected from server (ID {m_Connections[i].InternalId})");
  113. m_Connections[i] = default(NetworkConnection);
  114. }
  115. }
  116. }
  117. }
  118. }
  119. }