ServerHost.cs 2.5 KB

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