Skip to content

Instantly share code, notes, and snippets.

@Danil0v3s
Created November 4, 2023 16:51
Show Gist options
  • Save Danil0v3s/404dd7a787ce7615ca8bcfcf073a4c7e to your computer and use it in GitHub Desktop.
Save Danil0v3s/404dd7a787ce7615ca8bcfcf073a4c7e to your computer and use it in GitHub Desktop.
Jobified Transport
namespace Common.Network.JobSystem
{
using Unity.Burst;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Jobs;
using Unity.Networking.Transport;
using UnityEngine;
public struct ClientSendJob : IJob
{
public NetworkDriver Driver;
public NetworkPipeline Pipeline;
public NativeArray<NetworkConnection> Connection;
public NativeQueue<UnsafeList<byte>> Queue;
public void Execute()
{
if (!this.Connection[0].IsCreated) return;
var code = 0;
if ((code = this.Driver.BeginSend(this.Pipeline, this.Connection[0], out var writer)) == 0 && this.Queue.TryDequeue(out var byteArray))
{
foreach (var b in byteArray)
{
writer.WriteByte(b);
}
this.Driver.EndSend(writer);
}
Debug.Log($"BeginSend code {(Unity.Networking.Transport.Error.StatusCode)code}");
}
}
}
namespace Common.Network.JobSystem
{
using System;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using Unity.Networking.Transport;
using UnityEngine;
[BurstCompile]
public struct ClientUpdateJob : IJob
{
public NetworkDriver Driver;
public NativeArray<NetworkConnection> Connection;
public void Execute()
{
if (!this.Connection[0].IsCreated) return;
NetworkEvent.Type cmd;
while ((cmd = this.Driver.PopEventForConnection(this.Connection[0], out var stream)) != NetworkEvent.Type.Empty)
{
switch (cmd)
{
case NetworkEvent.Type.Empty:
Debug.Log("Empty data");
break;
case NetworkEvent.Type.Data:
Debug.Log("Data data");
break;
case NetworkEvent.Type.Connect:
Debug.Log("Connected");
break;
case NetworkEvent.Type.Disconnect:
Debug.Log("Disconnected");
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
}
}
namespace Common.Network
{
using System;
using Common.Network.JobSystem;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Jobs;
using Unity.Networking.Transport;
using Unity.Networking.Transport.Utilities;
using UnityEngine;
public class TransportNetworkClient : MonoBehaviour
{
private NetworkDriver _driver;
private NetworkPipeline _pipeline;
private NativeArray<NetworkConnection> _connection;
private NativeQueue<UnsafeList<byte>> _sendQueue;
private JobHandle _updateJobHandle;
private JobHandle _sendJobHandle;
private bool IsConnected = false;
#region Public API
public void Connect(string ip, int port)
{
var isEndpointValid = NetworkEndpoint.TryParse(ip, (ushort)port, out var endpoint);
if (!isEndpointValid)
{
Debug.LogError($"Invalid endpoint {ip}:{port}");
return;
}
this._connection = new NativeArray<NetworkConnection>(1, Allocator.Persistent);
this._connection[0] = this._driver.Connect(endpoint);
this.IsConnected = true;
}
public void Send(ArraySegment<byte> data)
{
return;
var unsafeList = new UnsafeList<byte>(data.Count, Allocator.Temp);
foreach (var b in data)
{
unsafeList.Add(b);
}
this._sendQueue.Enqueue(unsafeList);
}
#endregion
#region Lifecycle
private void Start()
{
this._driver = NetworkDriver.Create(new TCPNetworkInterface());
this._pipeline = this._driver.CreatePipeline(typeof(FragmentationPipelineStage));
this._sendQueue = new NativeQueue<UnsafeList<byte>>(Allocator.Persistent);
}
private void Update()
{
if (!this._connection.IsCreated) return;
var sendJob = new ClientSendJob
{
Driver = this._driver,
Pipeline = this._pipeline,
Connection = this._connection,
Queue = this._sendQueue,
};
var updateJob = new ClientUpdateJob
{
Driver = this._driver,
Connection = this._connection,
};
this._updateJobHandle = this._driver.ScheduleUpdate();
this._updateJobHandle = updateJob.Schedule(this._updateJobHandle);
this._sendJobHandle = this._driver.ScheduleFlushSend(this._updateJobHandle);
this._sendJobHandle = sendJob.Schedule(this._sendJobHandle);
}
private void LateUpdate()
{
// this._sendJobHandle.Complete();
this._updateJobHandle.Complete();
}
private void OnDestroy()
{
this.IsConnected = false;
this._updateJobHandle.Complete();
this._driver.Dispose();
this._connection.Dispose();
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment