|
@@ -1,21 +1,21 @@
|
|
|
-using System;
|
|
|
|
|
-using System.Collections.Generic;
|
|
|
|
|
|
|
+using System;
|
|
|
|
|
+using System.Collections.Generic;
|
|
|
using System.Runtime.InteropServices;
|
|
using System.Runtime.InteropServices;
|
|
|
-using System.Threading.Tasks;
|
|
|
|
|
-
|
|
|
|
|
|
|
+using System.Threading.Tasks;
|
|
|
|
|
+
|
|
|
namespace ENet
|
|
namespace ENet
|
|
|
{
|
|
{
|
|
|
public sealed class ESocket: IDisposable
|
|
public sealed class ESocket: IDisposable
|
|
|
{
|
|
{
|
|
|
private IntPtr peerPtr = IntPtr.Zero;
|
|
private IntPtr peerPtr = IntPtr.Zero;
|
|
|
- private readonly EService service;
|
|
|
|
|
- private readonly LinkedList<byte[]> recvBuffer = new LinkedList<byte[]>();
|
|
|
|
|
-
|
|
|
|
|
- public Action<EEvent> Connected { get; set; }
|
|
|
|
|
- public Action<EEvent> Received { get; set; }
|
|
|
|
|
- public Action<EEvent> Disconnect { get; set; }
|
|
|
|
|
- public Action<int> Error { get; set; }
|
|
|
|
|
-
|
|
|
|
|
|
|
+ private readonly EService service;
|
|
|
|
|
+ private readonly LinkedList<byte[]> recvBuffer = new LinkedList<byte[]>();
|
|
|
|
|
+
|
|
|
|
|
+ public Action<EEvent> Connected { get; set; }
|
|
|
|
|
+ public Action<EEvent> Received { get; set; }
|
|
|
|
|
+ public Action<EEvent> Disconnect { get; set; }
|
|
|
|
|
+ public Action<int> Error { get; set; }
|
|
|
|
|
+
|
|
|
public ESocket(EService service)
|
|
public ESocket(EService service)
|
|
|
{
|
|
{
|
|
|
this.service = service;
|
|
this.service = service;
|
|
@@ -100,58 +100,59 @@ namespace ENet
|
|
|
{
|
|
{
|
|
|
throw new EException("host connect call failed.");
|
|
throw new EException("host connect call failed.");
|
|
|
}
|
|
}
|
|
|
- this.service.PeersManager.Add(this.peerPtr, this);
|
|
|
|
|
- this.Connected = eEvent =>
|
|
|
|
|
- {
|
|
|
|
|
- if (eEvent.EventState == EventState.DISCONNECTED)
|
|
|
|
|
- {
|
|
|
|
|
- tcs.TrySetException(new EException("socket disconnected in connect"));
|
|
|
|
|
- }
|
|
|
|
|
- tcs.TrySetResult(true);
|
|
|
|
|
|
|
+ this.service.PeersManager.Add(this.peerPtr, this);
|
|
|
|
|
+ this.Connected = eEvent =>
|
|
|
|
|
+ {
|
|
|
|
|
+ if (eEvent.EventState == EventState.DISCONNECTED)
|
|
|
|
|
+ {
|
|
|
|
|
+ tcs.TrySetException(new EException("socket disconnected in connect"));
|
|
|
|
|
+ }
|
|
|
|
|
+ tcs.TrySetResult(true);
|
|
|
};
|
|
};
|
|
|
return tcs.Task;
|
|
return tcs.Task;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public Task<bool> AcceptAsync()
|
|
|
|
|
- {
|
|
|
|
|
- if (this.service.PeersManager.ContainsKey(IntPtr.Zero))
|
|
|
|
|
- {
|
|
|
|
|
- throw new EException("do not accept twice!");
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- var tcs = new TaskCompletionSource<bool>();
|
|
|
|
|
-
|
|
|
|
|
- // 如果有请求连接缓存的包,从缓存中取
|
|
|
|
|
- if (this.service.ConnEEvents.Count > 0)
|
|
|
|
|
- {
|
|
|
|
|
- EEvent eEvent = this.service.ConnEEvents.First.Value;
|
|
|
|
|
- this.service.ConnEEvents.RemoveFirst();
|
|
|
|
|
-
|
|
|
|
|
- this.PeerPtr = eEvent.PeerPtr;
|
|
|
|
|
- this.service.PeersManager.Add(this.PeerPtr, this);
|
|
|
|
|
-
|
|
|
|
|
- tcs.TrySetResult(true);
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ public Task<bool> AcceptAsync(Action action)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (this.service.PeersManager.ContainsKey(IntPtr.Zero))
|
|
|
|
|
+ {
|
|
|
|
|
+ throw new EException("do not accept twice!");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ var tcs = new TaskCompletionSource<bool>();
|
|
|
|
|
+
|
|
|
|
|
+ // 如果有请求连接缓存的包,从缓存中取
|
|
|
|
|
+ if (this.service.ConnEEvents.Count > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ EEvent eEvent = this.service.ConnEEvents.First.Value;
|
|
|
|
|
+ this.service.ConnEEvents.RemoveFirst();
|
|
|
|
|
+
|
|
|
|
|
+ this.PeerPtr = eEvent.PeerPtr;
|
|
|
this.service.PeersManager.Add(this.PeerPtr, this);
|
|
this.service.PeersManager.Add(this.PeerPtr, this);
|
|
|
- this.Connected = eEvent =>
|
|
|
|
|
- {
|
|
|
|
|
- if (eEvent.EventState == EventState.DISCONNECTED)
|
|
|
|
|
- {
|
|
|
|
|
- tcs.TrySetException(new EException("socket disconnected in accpet"));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- this.service.PeersManager.Remove(IntPtr.Zero);
|
|
|
|
|
-
|
|
|
|
|
- this.PeerPtr = eEvent.PeerPtr;
|
|
|
|
|
|
|
+ action();
|
|
|
|
|
+ tcs.TrySetResult(true);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ this.service.PeersManager.Add(this.PeerPtr, this);
|
|
|
|
|
+ this.Connected = eEvent =>
|
|
|
|
|
+ {
|
|
|
|
|
+ if (eEvent.EventState == EventState.DISCONNECTED)
|
|
|
|
|
+ {
|
|
|
|
|
+ tcs.TrySetException(new EException("socket disconnected in accpet"));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this.service.PeersManager.Remove(IntPtr.Zero);
|
|
|
|
|
+
|
|
|
|
|
+ this.PeerPtr = eEvent.PeerPtr;
|
|
|
this.service.PeersManager.Add(this.PeerPtr, this);
|
|
this.service.PeersManager.Add(this.PeerPtr, this);
|
|
|
- tcs.TrySetResult(true);
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ action();
|
|
|
|
|
+ tcs.TrySetResult(true);
|
|
|
|
|
+ };
|
|
|
}
|
|
}
|
|
|
return tcs.Task;
|
|
return tcs.Task;
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
public void WriteAsync(byte[] data, byte channelID = 0, PacketFlags flags = PacketFlags.Reliable)
|
|
public void WriteAsync(byte[] data, byte channelID = 0, PacketFlags flags = PacketFlags.Reliable)
|
|
|
{
|
|
{
|
|
|
var packet = new EPacket(data, flags);
|
|
var packet = new EPacket(data, flags);
|
|
@@ -162,39 +163,39 @@ namespace ENet
|
|
|
|
|
|
|
|
public Task<byte[]> ReadAsync()
|
|
public Task<byte[]> ReadAsync()
|
|
|
{
|
|
{
|
|
|
- var tcs = new TaskCompletionSource<byte[]>();
|
|
|
|
|
-
|
|
|
|
|
- // 如果有缓存的包,从缓存中取
|
|
|
|
|
- if (this.recvBuffer.Count > 0)
|
|
|
|
|
- {
|
|
|
|
|
- var bytes = this.recvBuffer.First.Value;
|
|
|
|
|
- this.recvBuffer.RemoveFirst();
|
|
|
|
|
- tcs.TrySetResult(bytes);
|
|
|
|
|
- }
|
|
|
|
|
- // 没有缓存封包,设置回调等待
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- this.Received = eEvent =>
|
|
|
|
|
- {
|
|
|
|
|
- if (eEvent.EventState == EventState.DISCONNECTED)
|
|
|
|
|
- {
|
|
|
|
|
- tcs.TrySetException(new EException("socket disconnected in receive"));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- using (var packet = new EPacket(eEvent.PacketPtr))
|
|
|
|
|
- {
|
|
|
|
|
- var bytes = packet.Bytes;
|
|
|
|
|
- tcs.TrySetResult(bytes);
|
|
|
|
|
- }
|
|
|
|
|
- };
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ var tcs = new TaskCompletionSource<byte[]>();
|
|
|
|
|
+
|
|
|
|
|
+ // 如果有缓存的包,从缓存中取
|
|
|
|
|
+ if (this.recvBuffer.Count > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ var bytes = this.recvBuffer.First.Value;
|
|
|
|
|
+ this.recvBuffer.RemoveFirst();
|
|
|
|
|
+ tcs.TrySetResult(bytes);
|
|
|
|
|
+ }
|
|
|
|
|
+ // 没有缓存封包,设置回调等待
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ this.Received = eEvent =>
|
|
|
|
|
+ {
|
|
|
|
|
+ if (eEvent.EventState == EventState.DISCONNECTED)
|
|
|
|
|
+ {
|
|
|
|
|
+ tcs.TrySetException(new EException("socket disconnected in receive"));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ using (var packet = new EPacket(eEvent.PacketPtr))
|
|
|
|
|
+ {
|
|
|
|
|
+ var bytes = packet.Bytes;
|
|
|
|
|
+ tcs.TrySetResult(bytes);
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
return tcs.Task;
|
|
return tcs.Task;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public Task<bool> DisconnectAsync(uint data = 0)
|
|
public Task<bool> DisconnectAsync(uint data = 0)
|
|
|
{
|
|
{
|
|
|
- NativeMethods.EnetPeerDisconnect(this.peerPtr, data);
|
|
|
|
|
- // EnetPeerDisconnect会reset Peer,这里设置为0,防止再次Dispose
|
|
|
|
|
|
|
+ NativeMethods.EnetPeerDisconnect(this.peerPtr, data);
|
|
|
|
|
+ // EnetPeerDisconnect会reset Peer,这里设置为0,防止再次Dispose
|
|
|
this.PeerPtr = IntPtr.Zero;
|
|
this.PeerPtr = IntPtr.Zero;
|
|
|
var tcs = new TaskCompletionSource<bool>();
|
|
var tcs = new TaskCompletionSource<bool>();
|
|
|
this.Disconnect = eEvent => tcs.TrySetResult(true);
|
|
this.Disconnect = eEvent => tcs.TrySetResult(true);
|
|
@@ -203,69 +204,69 @@ namespace ENet
|
|
|
|
|
|
|
|
public Task<bool> DisconnectLaterAsync(uint data = 0)
|
|
public Task<bool> DisconnectLaterAsync(uint data = 0)
|
|
|
{
|
|
{
|
|
|
- NativeMethods.EnetPeerDisconnectLater(this.peerPtr, data);
|
|
|
|
|
- // EnetPeerDisconnect会reset Peer,这里设置为0,防止再次Dispose
|
|
|
|
|
|
|
+ NativeMethods.EnetPeerDisconnectLater(this.peerPtr, data);
|
|
|
|
|
+ // EnetPeerDisconnect会reset Peer,这里设置为0,防止再次Dispose
|
|
|
this.PeerPtr = IntPtr.Zero;
|
|
this.PeerPtr = IntPtr.Zero;
|
|
|
- var tcs = new TaskCompletionSource<bool>();
|
|
|
|
|
|
|
+ var tcs = new TaskCompletionSource<bool>();
|
|
|
this.Disconnect = eEvent => tcs.TrySetResult(true);
|
|
this.Disconnect = eEvent => tcs.TrySetResult(true);
|
|
|
return tcs.Task;
|
|
return tcs.Task;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void DisconnectNow(uint data)
|
|
public void DisconnectNow(uint data)
|
|
|
{
|
|
{
|
|
|
- NativeMethods.EnetPeerDisconnectNow(this.peerPtr, data);
|
|
|
|
|
- // EnetPeerDisconnect会reset Peer,这里设置为0,防止再次Dispose
|
|
|
|
|
|
|
+ NativeMethods.EnetPeerDisconnectNow(this.peerPtr, data);
|
|
|
|
|
+ // EnetPeerDisconnect会reset Peer,这里设置为0,防止再次Dispose
|
|
|
this.PeerPtr = IntPtr.Zero;
|
|
this.PeerPtr = IntPtr.Zero;
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- internal void OnConnected(EEvent eEvent)
|
|
|
|
|
- {
|
|
|
|
|
- if (this.Connected == null)
|
|
|
|
|
- {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- Action<EEvent> localConnected = this.Connected;
|
|
|
|
|
- this.Connected = null;
|
|
|
|
|
- // 此调用将让await ConnectAsync返回,所以null必须在此之前设置
|
|
|
|
|
- localConnected(eEvent);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- internal void OnReceived(EEvent eEvent)
|
|
|
|
|
- {
|
|
|
|
|
- // 如果应用层还未调用readasync则将包放到缓存队列
|
|
|
|
|
- if (this.Received == null)
|
|
|
|
|
- {
|
|
|
|
|
- using (var packet = new EPacket(eEvent.PacketPtr))
|
|
|
|
|
- {
|
|
|
|
|
- var bytes = packet.Bytes;
|
|
|
|
|
- this.recvBuffer.AddLast(bytes);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- Action<EEvent> localReceived = this.Received;
|
|
|
|
|
- this.Received = null;
|
|
|
|
|
- // 此调用将让await ReadAsync返回,所以null必须在此之前设置
|
|
|
|
|
- localReceived(eEvent);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- internal void OnDisconnect(EEvent eEvent)
|
|
|
|
|
- {
|
|
|
|
|
- if (this.Disconnect == null)
|
|
|
|
|
- {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- this.Disconnect(eEvent);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- internal void OnError(int errorCode)
|
|
|
|
|
- {
|
|
|
|
|
- if (this.Error == null)
|
|
|
|
|
- {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- this.Error(errorCode);
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ internal void OnConnected(EEvent eEvent)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (this.Connected == null)
|
|
|
|
|
+ {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ Action<EEvent> localConnected = this.Connected;
|
|
|
|
|
+ this.Connected = null;
|
|
|
|
|
+ // 此调用将让await ConnectAsync返回,所以null必须在此之前设置
|
|
|
|
|
+ localConnected(eEvent);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ internal void OnReceived(EEvent eEvent)
|
|
|
|
|
+ {
|
|
|
|
|
+ // 如果应用层还未调用readasync则将包放到缓存队列
|
|
|
|
|
+ if (this.Received == null)
|
|
|
|
|
+ {
|
|
|
|
|
+ using (var packet = new EPacket(eEvent.PacketPtr))
|
|
|
|
|
+ {
|
|
|
|
|
+ var bytes = packet.Bytes;
|
|
|
|
|
+ this.recvBuffer.AddLast(bytes);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ Action<EEvent> localReceived = this.Received;
|
|
|
|
|
+ this.Received = null;
|
|
|
|
|
+ // 此调用将让await ReadAsync返回,所以null必须在此之前设置
|
|
|
|
|
+ localReceived(eEvent);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ internal void OnDisconnect(EEvent eEvent)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (this.Disconnect == null)
|
|
|
|
|
+ {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ this.Disconnect(eEvent);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ internal void OnError(int errorCode)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (this.Error == null)
|
|
|
|
|
+ {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ this.Error(errorCode);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|