ClientHost.cs 2.8 KB

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