WChannel_WebGL.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #if UNITY_WEBGL
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Net;
  6. using System.Runtime.InteropServices.ComTypes;
  7. using BestHTTP.WebSocket;
  8. using GFGGame;
  9. namespace ET
  10. {
  11. public class WChannel : AChannel
  12. {
  13. private readonly WService Service;
  14. private WebSocket webSocket;
  15. private Queue<MemoryStream> waitSend = new Queue<MemoryStream>();
  16. //address=http://webgltest.goufuguiwxw.com/ws
  17. public WChannel(long id, IPEndPoint ipEndPoint, WService service, string address)
  18. {
  19. this.Service = service;
  20. this.ChannelType = ChannelType.Connect;
  21. this.Id = id;
  22. string wsStr = $"ws://{ipEndPoint}";
  23. if (LauncherConfig.isHttps)
  24. {
  25. Uri uri = new Uri(address);
  26. string hostAndPath = uri.Host + uri.AbsolutePath;
  27. wsStr = $"wss://{hostAndPath}";
  28. }
  29. WebSocket ws = new WebSocket(new Uri(wsStr));
  30. if (LauncherConfig.isHttps)
  31. {
  32. this.RemoteAddress = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
  33. }
  34. else
  35. {
  36. this.RemoteAddress = ipEndPoint;
  37. }
  38. // Subscribe to the WS events
  39. ws.OnOpen += OnOpen;
  40. ws.OnClosed += OnClosed;
  41. ws.OnError += OnError;
  42. ws.OnBinary += OnRead;
  43. // Start connecting to the server
  44. ws.Open();
  45. }
  46. public override void Dispose()
  47. {
  48. if (this.IsDisposed)
  49. {
  50. return;
  51. }
  52. this.Id = 0;
  53. this.webSocket?.Close();
  54. this.webSocket = null;
  55. }
  56. public void Send(MemoryStream memoryBuffer)
  57. {
  58. switch (this.Service.ServiceType)
  59. {
  60. case ServiceType.Inner:
  61. break;
  62. case ServiceType.Outer:
  63. memoryBuffer.Seek(Packet.ActorIdLength, SeekOrigin.Begin);
  64. ;
  65. break;
  66. }
  67. if (this.webSocket == null)
  68. {
  69. this.waitSend.Enqueue(memoryBuffer);
  70. return;
  71. }
  72. SendOne(memoryBuffer);
  73. }
  74. private void SendOne(MemoryStream memoryBuffer)
  75. {
  76. this.webSocket.Send(memoryBuffer.GetBuffer(), (ulong)memoryBuffer.Position,
  77. (ulong)(memoryBuffer.Length - memoryBuffer.Position));
  78. }
  79. private void OnOpen(WebSocket ws)
  80. {
  81. if (ws == null)
  82. {
  83. this.OnError(ErrorCore.ERR_WebsocketConnectError);
  84. return;
  85. }
  86. if (this.IsDisposed)
  87. {
  88. return;
  89. }
  90. this.webSocket = ws;
  91. while (this.waitSend.Count > 0)
  92. {
  93. MemoryStream memoryBuffer = this.waitSend.Dequeue();
  94. this.SendOne(memoryBuffer);
  95. }
  96. }
  97. /// <summary>
  98. /// Called when we received a text message from the server
  99. /// </summary>
  100. private void OnRead(WebSocket ws, byte[] data)
  101. {
  102. if (this.IsDisposed)
  103. {
  104. return;
  105. }
  106. MemoryStream memoryBuffer = this.Service.Fetch();
  107. memoryBuffer.Write(data, 0, data.Length); // 写入整个 data
  108. memoryBuffer.Seek(2, SeekOrigin.Begin);
  109. this.Service.ReadCallback(this.Id, memoryBuffer);
  110. }
  111. /// <summary>
  112. /// Called when the web socket closed
  113. /// </summary>
  114. private void OnClosed(WebSocket ws, UInt16 code, string message)
  115. {
  116. if (this.IsDisposed)
  117. {
  118. return;
  119. }
  120. Log.Error($"wchannel closed: {code} {message}");
  121. this.OnError(0);
  122. }
  123. /// <summary>
  124. /// Called when an error occured on client side
  125. /// </summary>
  126. private void OnError(WebSocket ws, string error)
  127. {
  128. if (this.IsDisposed)
  129. {
  130. return;
  131. }
  132. //Log.Error($"WChannel error: {this.Id} {ws.GetHashCode()} {error}");
  133. this.OnError(ErrorCore.ERR_WebsocketError);
  134. }
  135. private void OnError(int error)
  136. {
  137. Log.Info($"WChannel error: {this.Id} {error}");
  138. long channelId = this.Id;
  139. this.Service.Remove(channelId);
  140. this.Service.ErrorCallback(channelId, error);
  141. }
  142. }
  143. }
  144. #endif