uniapp,h5

websocket.js 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import { Transport } from "../transport.js";
  2. import { pick, randomString } from "../util.js";
  3. import { encodePacket } from "engine.io-parser";
  4. import { globalThisShim as globalThis, nextTick } from "../globals.node.js";
  5. import debugModule from "debug"; // debug()
  6. const debug = debugModule("engine.io-client:websocket"); // debug()
  7. // detect ReactNative environment
  8. const isReactNative = typeof navigator !== "undefined" &&
  9. typeof navigator.product === "string" &&
  10. navigator.product.toLowerCase() === "reactnative";
  11. export class BaseWS extends Transport {
  12. get name() {
  13. return "websocket";
  14. }
  15. doOpen() {
  16. const uri = this.uri();
  17. const protocols = this.opts.protocols;
  18. // React Native only supports the 'headers' option, and will print a warning if anything else is passed
  19. const opts = isReactNative
  20. ? {}
  21. : pick(this.opts, "agent", "perMessageDeflate", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "localAddress", "protocolVersion", "origin", "maxPayload", "family", "checkServerIdentity");
  22. if (this.opts.extraHeaders) {
  23. opts.headers = this.opts.extraHeaders;
  24. }
  25. try {
  26. this.ws = this.createSocket(uri, protocols, opts);
  27. }
  28. catch (err) {
  29. return this.emitReserved("error", err);
  30. }
  31. this.ws.binaryType = this.socket.binaryType;
  32. this.addEventListeners();
  33. }
  34. /**
  35. * Adds event listeners to the socket
  36. *
  37. * @private
  38. */
  39. addEventListeners() {
  40. this.ws.onopen = () => {
  41. if (this.opts.autoUnref) {
  42. this.ws._socket.unref();
  43. }
  44. this.onOpen();
  45. };
  46. this.ws.onclose = (closeEvent) => this.onClose({
  47. description: "websocket connection closed",
  48. context: closeEvent,
  49. });
  50. this.ws.onmessage = (ev) => this.onData(ev.data);
  51. this.ws.onerror = (e) => this.onError("websocket error", e);
  52. }
  53. write(packets) {
  54. this.writable = false;
  55. // encodePacket efficient as it uses WS framing
  56. // no need for encodePayload
  57. for (let i = 0; i < packets.length; i++) {
  58. const packet = packets[i];
  59. const lastPacket = i === packets.length - 1;
  60. encodePacket(packet, this.supportsBinary, (data) => {
  61. // Sometimes the websocket has already been closed but the browser didn't
  62. // have a chance of informing us about it yet, in that case send will
  63. // throw an error
  64. try {
  65. this.doWrite(packet, data);
  66. }
  67. catch (e) {
  68. debug("websocket closed before onclose event");
  69. }
  70. if (lastPacket) {
  71. // fake drain
  72. // defer to next tick to allow Socket to clear writeBuffer
  73. nextTick(() => {
  74. this.writable = true;
  75. this.emitReserved("drain");
  76. }, this.setTimeoutFn);
  77. }
  78. });
  79. }
  80. }
  81. doClose() {
  82. if (typeof this.ws !== "undefined") {
  83. this.ws.close();
  84. this.ws = null;
  85. }
  86. }
  87. /**
  88. * Generates uri for connection.
  89. *
  90. * @private
  91. */
  92. uri() {
  93. const schema = this.opts.secure ? "wss" : "ws";
  94. const query = this.query || {};
  95. // append timestamp to URI
  96. if (this.opts.timestampRequests) {
  97. query[this.opts.timestampParam] = randomString();
  98. }
  99. // communicate binary support capabilities
  100. if (!this.supportsBinary) {
  101. query.b64 = 1;
  102. }
  103. return this.createUri(schema, query);
  104. }
  105. }
  106. const WebSocketCtor = globalThis.WebSocket || globalThis.MozWebSocket;
  107. /**
  108. * WebSocket transport based on the built-in `WebSocket` object.
  109. *
  110. * Usage: browser, Node.js (since v21), Deno, Bun
  111. *
  112. * @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
  113. * @see https://caniuse.com/mdn-api_websocket
  114. * @see https://nodejs.org/api/globals.html#websocket
  115. */
  116. export class WS extends BaseWS {
  117. createSocket(uri, protocols, opts) {
  118. return !isReactNative
  119. ? protocols
  120. ? new WebSocketCtor(uri, protocols)
  121. : new WebSocketCtor(uri)
  122. : new WebSocketCtor(uri, protocols, opts);
  123. }
  124. doWrite(_packet, data) {
  125. this.ws.send(data);
  126. }
  127. }