ClientHost.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. using System;
  2. using System.Threading.Tasks;
  3. using Log;
  4. namespace ENet
  5. {
  6. public sealed class ClientHost: Host
  7. {
  8. public ClientHost(
  9. uint peerLimit = NativeMethods.ENET_PROTOCOL_MAXIMUM_PEER_ID, uint channelLimit = 0,
  10. uint incomingBandwidth = 0, uint outgoingBandwidth = 0, bool enableCrc = true)
  11. {
  12. if (peerLimit > NativeMethods.ENET_PROTOCOL_MAXIMUM_PEER_ID)
  13. {
  14. throw new ArgumentOutOfRangeException("peerLimit");
  15. }
  16. CheckChannelLimit(channelLimit);
  17. this.host = NativeMethods.enet_host_create(
  18. IntPtr.Zero, peerLimit, channelLimit, incomingBandwidth, outgoingBandwidth);
  19. if (this.host == IntPtr.Zero)
  20. {
  21. throw new ENetException(0, "Host creation call failed.");
  22. }
  23. if (enableCrc)
  24. {
  25. this.EnableCrc();
  26. }
  27. }
  28. public Task<Peer> ConnectAsync(string hostName, ushort port,
  29. uint channelLimit = NativeMethods.ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT,
  30. uint data = 0)
  31. {
  32. CheckChannelLimit(channelLimit);
  33. var tcs = new TaskCompletionSource<Peer>();
  34. var address = new Address {HostName = hostName, Port = port};
  35. ENetAddress nativeAddress = address.Struct;
  36. IntPtr peerPtr = NativeMethods.enet_host_connect(
  37. this.host, ref nativeAddress, channelLimit, data);
  38. if (peerPtr == IntPtr.Zero)
  39. {
  40. throw new ENetException(0, "Host connect call failed.");
  41. }
  42. var peer = new Peer(peerPtr);
  43. this.PeersManager.Add(peerPtr, peer);
  44. peer.PeerEvent.Connected += e => tcs.TrySetResult(peer);
  45. return tcs.Task;
  46. }
  47. public void RunOnce(int timeout = 0)
  48. {
  49. this.OnEvents();
  50. if (this.Service(timeout) < 0)
  51. {
  52. return;
  53. }
  54. Event ev;
  55. while (this.CheckEvents(out ev) > 0)
  56. {
  57. switch (ev.Type)
  58. {
  59. case EventType.Connect:
  60. {
  61. var peer = this.PeersManager[ev.PeerPtr];
  62. peer.PeerEvent.OnConnected(ev);
  63. peer.PeerEvent.Connected = null;
  64. break;
  65. }
  66. case EventType.Receive:
  67. {
  68. var peer = this.PeersManager[ev.PeerPtr];
  69. peer.PeerEvent.OnReceived(ev);
  70. peer.PeerEvent.Received = null;
  71. break;
  72. }
  73. case EventType.Disconnect:
  74. {
  75. ev.EventState = EventState.DISCONNECTED;
  76. var peer = this.PeersManager[ev.PeerPtr];
  77. PeerEvent peerEvent = peer.PeerEvent;
  78. this.PeersManager.Remove(peer.PeerPtr);
  79. // enet_peer_disconnect会reset Peer,这里设置为0,防止再次Dispose
  80. peer.PeerPtr = IntPtr.Zero;
  81. if (peerEvent.Received != null)
  82. {
  83. peerEvent.OnReceived(ev);
  84. }
  85. else
  86. {
  87. peerEvent.OnDisconnect(ev);
  88. }
  89. break;
  90. }
  91. }
  92. }
  93. }
  94. public void Start(int timeout = 0)
  95. {
  96. while (this.isRunning)
  97. {
  98. this.RunOnce(timeout);
  99. }
  100. }
  101. }
  102. }