JobifiedClientBehaviour.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. using Unity.Jobs;
  4. using Unity.Collections;
  5. using Unity.Networking.Transport;
  6. using Sirenix.OdinInspector;
  7. using KairoEngine.Core;
  8. namespace KairoEngine.Multiplayer
  9. {
  10. [HideMonoScript]
  11. public class JobifiedClientBehaviour : MonoBehaviour
  12. {
  13. [HideInInspector] public NetworkDriver m_Driver;
  14. [HideInInspector] public NativeArray<NetworkConnection> m_Connection;
  15. [HideInInspector] public NativeArray<byte> m_Done;
  16. [HideInInspector] public JobHandle ClientJobHandle;
  17. [HideInInspector] private NativeQueue<JobEvent> m_eventQueue;
  18. public string address = "192.168.1.1";
  19. public ushort port = 9000;
  20. public bool autoConnectOnStart = true;
  21. private bool resourceLock = false;
  22. private int disconnectNow = 0;
  23. void Start ()
  24. {
  25. if(autoConnectOnStart) ConnectToServer();
  26. }
  27. public void ConnectToServer()
  28. {
  29. resourceLock = true;
  30. m_eventQueue = new NativeQueue<JobEvent>(Allocator.Persistent);
  31. m_Driver = NetworkDriver.Create();
  32. m_Connection = new NativeArray<NetworkConnection>(1, Allocator.Persistent);
  33. m_Done = new NativeArray<byte>(1, Allocator.Persistent);
  34. var endpoint = NetworkEndPoint.Parse(address, port);
  35. m_Connection[0] = m_Driver.Connect(endpoint);
  36. GenericEvents.Trigger("ClientEvent", $"Connecting to {address}:{port}");
  37. }
  38. public void DisconnectFromServer()
  39. {
  40. disconnectNow = 1;
  41. //m_Connection[0].Disconnect(m_Driver);
  42. //m_Connection[0] = default(NetworkConnection);
  43. //resourceLock = false;
  44. //Cleanup();
  45. //GenericEvents.Trigger("ClientEvent", $"Disconected from server");
  46. }
  47. public void OnDestroy()
  48. {
  49. Cleanup();
  50. }
  51. void Update()
  52. {
  53. if(resourceLock == false) return;
  54. ClientJobHandle.Complete();
  55. while(m_eventQueue.TryDequeue(out JobEvent jobEvent))
  56. {
  57. TriggerJobEvent(jobEvent);
  58. }
  59. if (!m_Connection[0].IsCreated && disconnectNow == 1)
  60. {
  61. Cleanup();
  62. return;
  63. }
  64. if (!m_Connection[0].IsCreated) return;
  65. var job = new ClientUpdateJob
  66. {
  67. driver = m_Driver,
  68. connection = m_Connection,
  69. done = m_Done,
  70. eventQueue = m_eventQueue.AsParallelWriter(),
  71. disconnect = disconnectNow
  72. };
  73. ClientJobHandle = m_Driver.ScheduleUpdate();
  74. ClientJobHandle = job.Schedule(ClientJobHandle);
  75. }
  76. public virtual void SendToServer(NetMsg msg)
  77. {
  78. DataStreamWriter writer;
  79. m_Driver.BeginSend(m_Connection[0], out writer);
  80. msg.Serialize(ref writer);
  81. m_Driver.EndSend(writer);
  82. }
  83. private void Cleanup()
  84. {
  85. if(resourceLock == false) return;
  86. ClientJobHandle.Complete();
  87. m_Connection.Dispose();
  88. m_Driver.Dispose();
  89. m_Done.Dispose();
  90. m_eventQueue.Dispose();
  91. resourceLock = false;
  92. disconnectNow = 0;
  93. }
  94. public void TriggerJobEvent(JobEvent jobEvent)
  95. {
  96. switch (jobEvent.code)
  97. {
  98. case 1:
  99. GenericEvents.Trigger("ClientEvent", $"Connected to server");
  100. break;
  101. case 2:
  102. GenericEvents.Trigger("ClientEvent", $"Disconnected from server");
  103. break;
  104. case 3:
  105. GenericEvents.Trigger("ClientEvent", $"Data received from server");
  106. break;
  107. case 4:
  108. GenericEvents.Trigger("ClientEvent", $"Error connecting to server");
  109. break;
  110. default:
  111. break;
  112. }
  113. }
  114. }
  115. struct ClientUpdateJob : IJob
  116. {
  117. public NetworkDriver driver;
  118. public NativeArray<NetworkConnection> connection;
  119. public NativeArray<byte> done;
  120. public NativeQueue<JobEvent>.ParallelWriter eventQueue;
  121. public int disconnect;
  122. public void Execute()
  123. {
  124. if (!connection[0].IsCreated)
  125. {
  126. if (done[0] != 1)
  127. Debug.Log("Something went wrong during connect");
  128. eventQueue.Enqueue(new JobEvent((int)NetworkingEvents.Message.ErrorConnectingToServer));
  129. return;
  130. }
  131. // Receive Data from connections
  132. DataStreamReader stream;
  133. NetworkEvent.Type cmd;
  134. while ((cmd = connection[0].PopEvent(driver, out stream)) != NetworkEvent.Type.Empty)
  135. {
  136. if (cmd == NetworkEvent.Type.Connect)
  137. {
  138. Debug.Log("We are now connected to the server");
  139. eventQueue.Enqueue(new JobEvent((int)NetworkingEvents.Message.ClientConnected));
  140. uint value = 1;
  141. DataStreamWriter writer = new DataStreamWriter();
  142. var result = driver.BeginSend(connection[0], out writer);
  143. writer.WriteUInt(value);
  144. driver.EndSend(writer);
  145. }
  146. else if (cmd == NetworkEvent.Type.Data)
  147. {
  148. uint value = stream.ReadUInt();
  149. Debug.Log("Got the value = " + value + " back from the server");
  150. eventQueue.Enqueue(new JobEvent((int)NetworkingEvents.Message.ClientReceivedData));
  151. // And finally change the `done[0]` to `1`
  152. done[0] = 1;
  153. //connection[0].Disconnect(driver);
  154. //connection[0] = default(NetworkConnection);
  155. //eventQueue.Enqueue(new JobEvent((int)NetworkingEvents.Message.Disconnected));
  156. }
  157. else if (cmd == NetworkEvent.Type.Disconnect)
  158. {
  159. eventQueue.Enqueue(new JobEvent((int)NetworkingEvents.Message.ClientDisconnected));
  160. Debug.Log("Client got disconnected from server");
  161. connection[0] = default(NetworkConnection);
  162. }
  163. }
  164. // Send Data to connections
  165. // Disconnect
  166. if(disconnect == 1)
  167. {
  168. eventQueue.Enqueue(new JobEvent((int)NetworkingEvents.Message.ClientDisconnected));
  169. Debug.Log("Client disconnected from server");
  170. connection[0].Disconnect(driver);
  171. connection[0] = default(NetworkConnection);
  172. }
  173. }
  174. }
  175. }