Last active
July 6, 2016 01:59
-
-
Save NVentimiglia/2534ab5dac563565887ee2e9b9ebd3dc to your computer and use it in GitHub Desktop.
LiteNetUdp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using SignalMQ.Data; | |
using System.Threading.Tasks; | |
using LiteNetLib; | |
using LiteNetLib.Utils; | |
namespace SignalMQ.Transports.Udp | |
{ | |
/// <summary> | |
/// A tcp connection | |
/// </summary> | |
public class NetUdpClientTransport : ClientTransport, INetEventListener | |
{ | |
private NetClient _netClient; | |
private NetPeer _peer; | |
private Action<SignalCallback> openCallback; | |
private string endpoint; | |
private string key; | |
private int port; | |
private bool closing; | |
public int Ping = 0; | |
public NetUdpClientTransport(string endpoint, int port, string key = "SignalMQ") | |
{ | |
this.endpoint = endpoint; | |
this.port = port; | |
this.key = key; | |
} | |
public override void Open(Action<SignalCallback> callback = null) | |
{ | |
try | |
{ | |
if (State != ClientState.Closed) | |
{ | |
RaiseError(SignalException.AlreadyConnected); | |
if (callback != null) | |
{ | |
callback(new SignalCallback { Exception = SignalException.AlreadyConnected.Message }); | |
} | |
return; | |
} | |
if (_netClient != null) | |
{ | |
Close(); | |
} | |
openCallback = callback; | |
State = ClientState.Opening; | |
_netClient = new NetClient(this, key); | |
_netClient.Start(); | |
_netClient.Connect(endpoint, port); | |
_netClient.UpdateTime = 15; | |
Task.Factory.StartNew(ReceiveAsync, TaskCreationOptions.LongRunning); | |
} | |
catch (Exception ex) | |
{ | |
RaiseError(ex); | |
Close(); | |
if (openCallback != null) | |
{ | |
openCallback(new SignalCallback { Exception = ex.Message }); | |
openCallback = null; | |
} | |
} | |
} | |
protected override void OnOpened() | |
{ | |
if (openCallback != null) | |
{ | |
openCallback(new SignalCallback { Success = true }); | |
openCallback = null; | |
} | |
} | |
public override void Send(Signal signal) | |
{ | |
try | |
{ | |
if (_peer == null || closing || State == ClientState.Closed) | |
{ | |
return; | |
} | |
_peer.Send(signal.Data, 0, signal.Size, SendOptions.Unreliable); | |
} | |
catch (Exception ex) | |
{ | |
RaiseError(ex); | |
Close(); | |
} | |
} | |
// | |
public override void Close() | |
{ | |
closing = true; | |
if (closing) | |
return; | |
if (_netClient != null && State == ClientState.Opened) | |
{ | |
var signal = new Signal(Signal.SignalSize.SIZE_HEADER, Signal.ROUTE_SERVER, UtilitySignals.CloseSignal); | |
Send(signal); | |
} | |
if (_netClient != null) | |
{ | |
_netClient.Stop(); | |
_netClient = null; | |
} | |
if (State == ClientState.Closed) | |
{ | |
return; | |
} | |
State = ClientState.Closed; | |
if (openCallback != null) | |
{ | |
openCallback(new SignalCallback { Exception = SignalException.ConnectionAborted.Message }); | |
openCallback = null; | |
} | |
} | |
public async Task ReceiveAsync() | |
{ | |
try | |
{ | |
while (_netClient != null) | |
{ | |
_netClient.PollEvents(); | |
// await Task.Yield(); | |
} | |
} | |
catch (Exception ex) | |
{ | |
RaiseError(ex); | |
Close(); | |
} | |
} | |
void HandleMessage(byte[] buffer) | |
{ | |
try | |
{ | |
if (buffer == null || buffer.Length == 0) | |
return; | |
var signal = new Signal(buffer); | |
if (ProcessSignal(signal)) | |
RaiseData(signal); | |
} | |
catch (Exception ex) | |
{ | |
RaiseError(ex); | |
if (openCallback != null) | |
{ | |
openCallback(new SignalCallback { Exception = ex.Message }); | |
openCallback = null; | |
} | |
Close(); | |
} | |
} | |
public void OnPeerConnected(NetPeer peer) | |
{ | |
_peer = peer; | |
} | |
public void OnPeerDisconnected(NetPeer peer, string additionalInfo) | |
{ | |
//_peer = null; | |
} | |
public void OnNetworkError(NetEndPoint endPoint, string error) | |
{ | |
RaiseError(new Exception(error)); | |
} | |
public void OnNetworkReceive(NetPeer peer, NetDataReader reader) | |
{ | |
HandleMessage(reader.Data); | |
} | |
public void OnNetworkReceiveUnconnected(NetEndPoint remoteEndPoint, NetDataReader reader) | |
{ | |
HandleMessage(reader.Data); | |
} | |
public void OnNetworkLatencyUpdate(NetPeer peer, int latency) | |
{ | |
Ping = latency; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Net; | |
using System.Net.Sockets; | |
using System.Threading.Tasks; | |
using LiteNetLib; | |
using SignalMQ.Data; | |
namespace SignalMQ.Transports.Udp | |
{ | |
/// <summary> | |
/// </summary> | |
public class NetUdpConnection : ServerConnection | |
{ | |
public static Task Empty = Task.FromResult(string.Empty); | |
public override bool IsOpen | |
{ | |
get { return host != null && !hasTermination && host.IsOpen && peer != null; } | |
} | |
private NetPeer peer; | |
private NetUdpServerTransport host; | |
private bool hasTermination; | |
public NetUdpConnection(NetUdpServerTransport host, NetPeer peer) | |
{ | |
this.peer = peer; | |
this.host = host; | |
} | |
public override async Task Send(Signal signal) | |
{ | |
if (!IsOpen) | |
{ | |
await Empty; | |
} | |
try | |
{ | |
peer.Send(signal.Data, 0, signal.Size, SendOptions.Unreliable); | |
} | |
catch (Exception ex) | |
{ | |
OnError(this, new Exception("Error while sending", ex)); | |
Close(); | |
} | |
} | |
public void HandleClose() | |
{ | |
hasTermination = true; | |
Close(); | |
} | |
public void HandleError(string error) | |
{ | |
OnError(this, new Exception(error)); | |
} | |
internal void HandleReceive(byte[] data) | |
{ | |
var signal = new Signal(data); | |
if (ProcessSignal(signal)) | |
OnData(this, signal); | |
} | |
public override async void Close() | |
{ | |
if (IsOpen) | |
{ | |
using (var signal = new Signal(Signal.SignalSize.SIZE_HEADER, Signal.ROUTE_SERVER, UtilitySignals.CloseSignal)) | |
{ | |
await Send(signal); | |
} | |
} | |
hasTermination = true; | |
if (peer != null) | |
{ | |
peer = null; | |
OnClose(this); | |
} | |
host = null; | |
OnOpen = null; | |
OnClose = null; | |
OnData = null; | |
OnLog = null; | |
OnError = null; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Concurrent; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading.Tasks; | |
using SignalMQ.Data; | |
using LiteNetLib; | |
using LiteNetLib.Utils; | |
namespace SignalMQ.Transports.Udp | |
{ | |
public class NetUdpServerTransport : ServerTransport, INetEventListener | |
{ | |
static Task Empty = Task.FromResult(string.Empty); | |
public NetServer Server; | |
public Dictionary<NetPeer, NetUdpConnection> Peers; | |
int maxClients; | |
private int port; | |
string key; | |
public override bool IsOpen { get { return Server != null && Server.IsRunning; } } | |
public NetUdpServerTransport(int port, int maxClients = 1000, string key = "SignalMQ") | |
{ | |
this.maxClients = maxClients; | |
this.key = key; | |
this.port = port; | |
} | |
public override IEnumerable<ServerConnection> Connections() | |
{ | |
return Peers.Values; | |
} | |
public override Task Send(Signal signal) | |
{ | |
Server.SendToClients(signal.Data, 0, signal.Size, (SendOptions)signal.Option); | |
return Empty; | |
} | |
public override void Open() | |
{ | |
if (IsOpen) | |
return; | |
try | |
{ | |
Peers = new Dictionary<NetPeer, NetUdpConnection>(); | |
Server = new NetServer(this, maxClients, key); | |
Server.Start(port); | |
Task.Factory.StartNew(ReceiveAsync, TaskCreationOptions.LongRunning); | |
Console.WriteLine("SignalMQ.UdpServerTransport Running"); | |
} | |
catch (Exception ex) | |
{ | |
RaiseError(ex); | |
Close(); | |
} | |
} | |
public async void ReceiveAsync() | |
{ | |
try | |
{ | |
while (IsOpen) | |
{ | |
Server.PollEvents(); | |
// await Task.Yield(); | |
} | |
} | |
catch (Exception e) | |
{ | |
RaiseError(e); | |
} | |
finally | |
{ | |
Close(); | |
} | |
} | |
public override void Close() | |
{ | |
if (!IsOpen) | |
return; | |
if (Peers != null) | |
{ | |
foreach (var connection in Peers) | |
{ | |
connection.Value.Close(); | |
} | |
Peers = null; | |
} | |
if (Server != null) | |
{ | |
Server.Stop(); | |
Server = null; | |
} | |
} | |
public async void OnPeerConnected(NetPeer peer) | |
{ | |
var proxy = new NetUdpConnection(this, peer); | |
BindConnection(proxy); | |
Peers.Add(peer, proxy); | |
await proxy.Init(); | |
} | |
public void OnPeerDisconnected(NetPeer peer, string additionalInfo) | |
{ | |
if (Peers.ContainsKey(peer)) | |
{ | |
Peers[peer].HandleClose(); | |
Peers.Remove(peer); | |
} | |
} | |
public void OnNetworkError(NetEndPoint endPoint, string error) | |
{ | |
var peer = Server.GetPeers().FirstOrDefault(o => o.EndPoint == endPoint); | |
if (peer != null) | |
{ | |
NetUdpConnection match; | |
Peers.TryGetValue(peer, out match); | |
if (match != null) | |
{ | |
match.HandleError(error); | |
} | |
else | |
{ | |
RaiseError(new Exception(error)); | |
} | |
} | |
} | |
public void OnNetworkReceive(NetPeer peer, NetDataReader reader) | |
{ | |
NetUdpConnection match; | |
Peers.TryGetValue(peer, out match); | |
if (match != null) | |
{ | |
match.HandleReceive(reader.Data); | |
} | |
} | |
public void OnNetworkReceiveUnconnected(NetEndPoint remoteEndPoint, NetDataReader reader) | |
{ | |
} | |
public void OnNetworkLatencyUpdate(NetPeer peer, int latency) | |
{ | |
NetUdpConnection match; | |
Peers.TryGetValue(peer, out match); | |
if (match != null) | |
{ | |
// match.Session["Latency"] = latency; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment