BestHTTP_WebSocket.jslib 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. var Lib_BEST_HTTP_WebGL_WS_Bridge =
  2. {
  3. $ws: {
  4. webSocketInstances: {},
  5. nextInstanceId : 1,
  6. halt: false,
  7. /*UTF8Decoder: new TextDecoder('utf8'),*/
  8. Set : function(socket) {
  9. ws.webSocketInstances[ws.nextInstanceId] = socket;
  10. return ws.nextInstanceId++;
  11. },
  12. Get : function(id) {
  13. return ws.webSocketInstances[id];
  14. },
  15. Remove: function(id) {
  16. delete ws.webSocketInstances[id];
  17. },
  18. _callOnClose: function(onClose, id, code, reason)
  19. {
  20. if (ws.halt) return;
  21. var length = lengthBytesUTF8(reason) + 1;
  22. var buffer = _malloc(length);
  23. stringToUTF8Array(reason, HEAPU8, buffer, length);
  24. Module['dynCall_viii'](onClose, id, code, buffer);
  25. _free(buffer);
  26. },
  27. _callOnError: function(errCallback, id, reason)
  28. {
  29. if (ws.halt) return;
  30. var length = lengthBytesUTF8(reason) + 1;
  31. var buffer = _malloc(length);
  32. stringToUTF8Array(reason, HEAPU8, buffer, length);
  33. Module['dynCall_vii'](errCallback, id, buffer);
  34. _free(buffer);
  35. }
  36. },
  37. WS_EmergencyRelease: function() {
  38. console.log('WS_EmergencyRelease');
  39. ws.halt = true;
  40. },
  41. WS_Create: function(url, protocol, onOpen, onText, onBinary, onError, onClose)
  42. {
  43. var urlStr = new URL(UTF8ToString(url)); ///*encodeURI*/(UTF8ToString(url)).replace(/\+/g, '%2B').replace(/%252[fF]/ig, '%2F');
  44. var proto = UTF8ToString(protocol);
  45. console.log('WS_Create(' + urlStr + ', "' + proto + '")');
  46. var socket = {
  47. onError: onError,
  48. onClose: onClose
  49. };
  50. if (proto == '')
  51. socket.socketImpl = new WebSocket(urlStr);
  52. else
  53. socket.socketImpl = new WebSocket(urlStr, [proto]);
  54. var id = ws.nextInstanceId;
  55. socket.socketImpl.binaryType = "arraybuffer";
  56. socket.socketImpl.onopen = function(e) {
  57. console.log(id + ' WS_Create - onOpen');
  58. if (ws.halt) return;
  59. Module['dynCall_vi'](onOpen, id);
  60. };
  61. socket.socketImpl.onmessage = function (e)
  62. {
  63. if (ws.halt) return;
  64. // Binary?
  65. if (e.data instanceof ArrayBuffer)
  66. {
  67. var byteArray = new Uint8Array(e.data);
  68. var buffer = _malloc(byteArray.length);
  69. HEAPU8.set(byteArray, buffer);
  70. Module['dynCall_viii'](onBinary, id, buffer, byteArray.length);
  71. _free(buffer);
  72. }
  73. else // Text
  74. {
  75. var length = lengthBytesUTF8(e.data) + 1;
  76. var buffer = _malloc(length);
  77. stringToUTF8Array(e.data, HEAPU8, buffer, length);
  78. Module['dynCall_vii'](onText, id, buffer);
  79. _free(buffer);
  80. }
  81. };
  82. socket.socketImpl.onerror = function (e)
  83. {
  84. console.log(id + ' WS_Create - onError');
  85. if (ws.halt) return;
  86. // Do not call this, onClose will be called with an apropriate error code and reason
  87. //ws._callOnError(onError, id, "Unknown error.");
  88. };
  89. socket.socketImpl.onclose = function (e) {
  90. console.log(id + ' WS_Create - onClose ' + e.code + ' ' + e.reason);
  91. if (ws.halt) return;
  92. //if (e.code != 1000)
  93. //{
  94. // if (e.reason != null && e.reason.length > 0)
  95. // ws._callOnError(onError, id, e.reason);
  96. // else
  97. // {
  98. // switch (e.code)
  99. // {
  100. // case 1001: ws._callOnError(onError, id, "Endpoint going away.");
  101. // break;
  102. // case 1002: ws._callOnError(onError, id, "Protocol error.");
  103. // break;
  104. // case 1003: ws._callOnError(onError, id, "Unsupported message.");
  105. // break;
  106. // case 1005: ws._callOnError(onError, id, "No status.");
  107. // break;
  108. // case 1006: ws._callOnError(onError, id, "Abnormal disconnection.");
  109. // break;
  110. // case 1009: ws._callOnError(onError, id, "Data frame too large.");
  111. // break;
  112. // default: ws._callOnError(onError, id, "Error " + e.code);
  113. // }
  114. // }
  115. //}
  116. //else
  117. ws._callOnClose(onClose, id, e.code, e.reason);
  118. };
  119. return ws.Set(socket);
  120. },
  121. WS_GetState: function (id)
  122. {
  123. var socket = ws.Get(id);
  124. if (typeof socket === 'undefined' ||
  125. socket == null ||
  126. typeof socket.socketImpl === 'undefined' ||
  127. socket.socketImpl == null)
  128. return 3; // closed
  129. return socket.socketImpl.readyState;
  130. },
  131. WS_GetBufferedAmount: function (id)
  132. {
  133. var socket = ws.Get(id);
  134. return socket.socketImpl.bufferedAmount;
  135. },
  136. WS_Send_String: function (id, ptr, pos, length)
  137. {
  138. var socket = ws.Get(id);
  139. var startPtr = ptr + pos;
  140. var endPtr = startPtr + length;
  141. var UTF8Decoder = new TextDecoder('utf8');
  142. var str = UTF8Decoder.decode(HEAPU8.subarray ? HEAPU8.subarray(startPtr, endPtr) : new Uint8Array(HEAPU8.slice(startPtr, endPtr)));
  143. try
  144. {
  145. socket.socketImpl.send(str);
  146. }
  147. catch(e) {
  148. ws._callOnError(socket.onError, id, ' ' + e.name + ': ' + e.message);
  149. }
  150. return socket.socketImpl.bufferedAmount;
  151. },
  152. WS_Send_Binary: function(id, ptr, pos, length)
  153. {
  154. var socket = ws.Get(id);
  155. try
  156. {
  157. var buff = HEAPU8.subarray(ptr + pos, ptr + pos + length);
  158. socket.socketImpl.send(buff /*HEAPU8.buffer.slice(ptr + pos, ptr + pos + length)*/);
  159. }
  160. catch(e) {
  161. ws._callOnError(socket.onError, id, ' ' + e.name + ': ' + e.message);
  162. }
  163. return socket.socketImpl.bufferedAmount;
  164. },
  165. WS_Close: function (id, code, reason)
  166. {
  167. var socket = ws.Get(id);
  168. var reasonStr = UTF8ToString(reason);
  169. console.log(id + ' WS_Close(' + code + ', ' + reasonStr + ')');
  170. socket.socketImpl.close(/*ulong*/code, reasonStr);
  171. },
  172. WS_Release: function(id)
  173. {
  174. console.log(id + ' WS_Release');
  175. ws.Remove(id);
  176. }
  177. };
  178. autoAddDeps(Lib_BEST_HTTP_WebGL_WS_Bridge, '$ws');
  179. mergeInto(LibraryManager.library, Lib_BEST_HTTP_WebGL_WS_Bridge);