WChannel_WebGL.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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=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 (!string.IsNullOrEmpty(address))
  24. {
  25. wsStr = wsStr = $"ws://{address}";
  26. if (LauncherConfig.isHttps)
  27. {
  28. //wsStr = $"wss://webgltest.goufuguiwxw.com/ws";
  29. wsStr = $"wss://{address}";
  30. }
  31. }
  32. else
  33. {
  34. if (LauncherConfig.isHttps)
  35. {
  36. wsStr = $"wss://{ipEndPoint}";
  37. }
  38. this.RemoteAddress = ipEndPoint;
  39. }
  40. WebSocket ws = new WebSocket(new Uri(wsStr));
  41. if (LauncherConfig.isHttps)
  42. {
  43. this.RemoteAddress = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
  44. }
  45. else
  46. {
  47. this.RemoteAddress = ipEndPoint;
  48. }
  49. // Subscribe to the WS events
  50. ws.OnOpen += OnOpen;
  51. ws.OnClosed += OnClosed;
  52. ws.OnError += OnError;
  53. ws.OnBinary += OnRead;
  54. // Start connecting to the server
  55. ws.Open();
  56. }
  57. public override void Dispose()
  58. {
  59. if (this.IsDisposed)
  60. {
  61. return;
  62. }
  63. this.Id = 0;
  64. this.webSocket?.Close();
  65. this.webSocket = null;
  66. }
  67. public void Send(MemoryStream memoryBuffer)
  68. {
  69. switch (this.Service.ServiceType)
  70. {
  71. case ServiceType.Inner:
  72. break;
  73. case ServiceType.Outer:
  74. memoryBuffer.Seek(Packet.ActorIdLength, SeekOrigin.Begin);
  75. ;
  76. break;
  77. }
  78. if (this.webSocket == null)
  79. {
  80. this.waitSend.Enqueue(memoryBuffer);
  81. return;
  82. }
  83. SendOne(memoryBuffer);
  84. }
  85. private void SendOne(MemoryStream memoryBuffer)
  86. {
  87. this.webSocket.Send(memoryBuffer.GetBuffer(), (ulong)memoryBuffer.Position,
  88. (ulong)(memoryBuffer.Length - memoryBuffer.Position));
  89. }
  90. private void OnOpen(WebSocket ws)
  91. {
  92. if (ws == null)
  93. {
  94. this.OnError(ErrorCore.ERR_WebsocketConnectError);
  95. return;
  96. }
  97. if (this.IsDisposed)
  98. {
  99. return;
  100. }
  101. this.webSocket = ws;
  102. while (this.waitSend.Count > 0)
  103. {
  104. MemoryStream memoryBuffer = this.waitSend.Dequeue();
  105. this.SendOne(memoryBuffer);
  106. }
  107. }
  108. /// <summary>
  109. /// Called when we received a text message from the server
  110. /// </summary>
  111. private void OnRead(WebSocket ws, byte[] data)
  112. {
  113. if (this.IsDisposed)
  114. {
  115. return;
  116. }
  117. MemoryStream memoryBuffer = this.Service.Fetch();
  118. memoryBuffer.Write(data, 0, data.Length); // 写入整个 data
  119. memoryBuffer.Seek(2, SeekOrigin.Begin);
  120. this.Service.ReadCallback(this.Id, memoryBuffer);
  121. }
  122. /// <summary>
  123. /// Called when the web socket closed
  124. /// </summary>
  125. private void OnClosed(WebSocket ws, UInt16 code, string message)
  126. {
  127. if (this.IsDisposed)
  128. {
  129. return;
  130. }
  131. Log.Error($"wchannel closed: {code} {message}");
  132. this.OnError(0);
  133. }
  134. /// <summary>
  135. /// Called when an error occured on client side
  136. /// </summary>
  137. private void OnError(WebSocket ws, string error)
  138. {
  139. if (this.IsDisposed)
  140. {
  141. return;
  142. }
  143. //Log.Error($"WChannel error: {this.Id} {ws.GetHashCode()} {error}");
  144. this.OnError(ErrorCore.ERR_WebsocketError);
  145. }
  146. private void OnError(int error)
  147. {
  148. Log.Info($"WChannel error: {this.Id} {error}");
  149. long channelId = this.Id;
  150. this.Service.Remove(channelId);
  151. this.Service.ErrorCallback(channelId, error);
  152. }
  153. }
  154. }
  155. #endif