123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.Assertions;
- using Unity.Jobs;
- using Unity.Collections;
- using Unity.Networking.Transport;
- using Sirenix.OdinInspector;
- using KairoEngine.Core;
- namespace KairoEngine.Multiplayer
- {
- [HideMonoScript]
- public class JobifiedServerBehaviour : MonoBehaviour
- {
- [HideInInspector] public NetworkDriver m_Driver;
- [HideInInspector] public NativeList<NetworkConnection> m_Connections;
- public ushort port = 9000;
- public int players = 4;
- public bool autoStart = true;
- private JobHandle ServerJobHandle;
- [HideInInspector] private NativeQueue<JobEvent> m_eventQueue;
- private bool resourceLock = false;
- void Start ()
- {
- if(autoStart) StartServer();
- }
- public void StartServer()
- {
- resourceLock = true;
- m_eventQueue = new NativeQueue<JobEvent>(Allocator.Persistent);
- m_Connections = new NativeList<NetworkConnection>(players, Allocator.Persistent);
- m_Driver = NetworkDriver.Create();
- var endpoint = NetworkEndPoint.AnyIpv4;
- endpoint.Port = port;
- if (m_Driver.Bind(endpoint) != 0)
- {
- Debug.Log($"Failed to bind to port {port}");
- GenericEvents.Trigger("ServerEvent", $"Failed to bind to port {port}");
- }
- else
- {
- Debug.Log($"Server listening on port {port}");
- GenericEvents.Trigger("ServerEvent", $"Server listening on port {port}");
- m_Driver.Listen();
- }
- }
- public void OnDestroy()
- {
- // Make sure we run our jobs to completion before exiting.
- ServerJobHandle.Complete();
- m_Connections.Dispose();
- m_Driver.Dispose();
- m_eventQueue.Dispose();
- }
- void Update ()
- {
- if(resourceLock == false) return;
- ServerJobHandle.Complete();
- while(m_eventQueue.TryDequeue(out JobEvent jobEvent))
- {
- TriggerJobEvent(jobEvent);
- }
- var connectionJob = new ServerUpdateConnectionsJob
- {
- driver = m_Driver,
- connections = m_Connections,
- eventQueue = m_eventQueue.AsParallelWriter()
- };
- var serverUpdateJob = new ServerUpdateJob
- {
- driver = m_Driver.ToConcurrent(),
- connections = m_Connections.AsDeferredJobArray(),
- eventQueue = m_eventQueue.AsParallelWriter(),
- };
- ServerJobHandle = m_Driver.ScheduleUpdate();
- ServerJobHandle = connectionJob.Schedule(ServerJobHandle);
- ServerJobHandle = serverUpdateJob.Schedule(m_Connections, 1, ServerJobHandle);
- }
- public void TriggerJobEvent(JobEvent jobEvent)
- {
- switch (jobEvent.code)
- {
- case 1:
- GenericEvents.Trigger("ServerEvent", $"Client connected ");
- break;
- case 2:
- GenericEvents.Trigger("ServerEvent", $"Client disconnected");
- break;
- case 3:
- GenericEvents.Trigger("ServerEvent", $"Data received from client");
- break;
- case 4:
- GenericEvents.Trigger("ServerEvent", $"Error connecting to client");
- break;
- default:
- break;
- }
- }
- }
- struct ServerUpdateConnectionsJob : IJob
- {
- public NetworkDriver driver;
- public NativeList<NetworkConnection> connections;
- public NativeQueue<JobEvent>.ParallelWriter eventQueue;
- public void Execute()
- {
- // CleanUpConnections
- for (int i = 0; i < connections.Length; i++)
- {
- if (!connections[i].IsCreated)
- {
- connections.RemoveAtSwapBack(i);
- --i;
- }
- }
- // AcceptNewConnections
- NetworkConnection c;
- while ((c = driver.Accept()) != default(NetworkConnection))
- {
- connections.Add(c);
- Debug.Log("Accepted a connection");
- eventQueue.Enqueue(new JobEvent((int)NetworkingEvents.Message.ClientConnected));
- }
- }
- }
- struct ServerUpdateJob : IJobParallelForDefer
- {
- public NetworkDriver.Concurrent driver;
- public NativeArray<NetworkConnection> connections;
- public NativeQueue<JobEvent>.ParallelWriter eventQueue;
- public void Execute(int index)
- {
- DataStreamReader stream;
- Assert.IsTrue(connections[index].IsCreated);
- // Receive data from clients
- NetworkEvent.Type cmd;
- while ((cmd = driver.PopEventForConnection(connections[index], out stream)) != NetworkEvent.Type.Empty)
- {
- if (cmd == NetworkEvent.Type.Data)
- {
- eventQueue.Enqueue(new JobEvent((int)NetworkingEvents.Message.ServerReceivedData));
- uint number = stream.ReadUInt();
- Debug.Log("Got " + number + " from the Client adding + 2 to it.");
- number +=2;
- DataStreamWriter writer = new DataStreamWriter();
- var result = driver.BeginSend(connections[index], out writer);
- writer.WriteUInt(number);
- driver.EndSend(writer);
- }
- else if (cmd == NetworkEvent.Type.Disconnect)
- {
- eventQueue.Enqueue(new JobEvent((int)NetworkingEvents.Message.ClientDisconnected));
- Debug.Log("Client disconnected from server");
- connections[index] = default(NetworkConnection);
- }
- }
- // Send data to clients
- }
- }
- }
|