polling.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. exports.Polling = void 0;
  7. const transport_js_1 = require("../transport.js");
  8. const debug_1 = __importDefault(require("debug")); // debug()
  9. const yeast_1 = __importDefault(require("yeast"));
  10. const parseqs_1 = __importDefault(require("parseqs"));
  11. const engine_io_parser_1 = require("engine.io-parser");
  12. const debug = (0, debug_1.default)("engine.io-client:polling"); // debug()
  13. class Polling extends transport_js_1.Transport {
  14. constructor() {
  15. super(...arguments);
  16. this.polling = false;
  17. }
  18. /**
  19. * Transport name.
  20. */
  21. get name() {
  22. return "polling";
  23. }
  24. /**
  25. * Opens the socket (triggers polling). We write a PING message to determine
  26. * when the transport is open.
  27. *
  28. * @api private
  29. */
  30. doOpen() {
  31. this.poll();
  32. }
  33. /**
  34. * Pauses polling.
  35. *
  36. * @param {Function} callback upon buffers are flushed and transport is paused
  37. * @api private
  38. */
  39. pause(onPause) {
  40. this.readyState = "pausing";
  41. const pause = () => {
  42. debug("paused");
  43. this.readyState = "paused";
  44. onPause();
  45. };
  46. if (this.polling || !this.writable) {
  47. let total = 0;
  48. if (this.polling) {
  49. debug("we are currently polling - waiting to pause");
  50. total++;
  51. this.once("pollComplete", function () {
  52. debug("pre-pause polling complete");
  53. --total || pause();
  54. });
  55. }
  56. if (!this.writable) {
  57. debug("we are currently writing - waiting to pause");
  58. total++;
  59. this.once("drain", function () {
  60. debug("pre-pause writing complete");
  61. --total || pause();
  62. });
  63. }
  64. }
  65. else {
  66. pause();
  67. }
  68. }
  69. /**
  70. * Starts polling cycle.
  71. *
  72. * @api public
  73. */
  74. poll() {
  75. debug("polling");
  76. this.polling = true;
  77. this.doPoll();
  78. this.emit("poll");
  79. }
  80. /**
  81. * Overloads onData to detect payloads.
  82. *
  83. * @api private
  84. */
  85. onData(data) {
  86. debug("polling got data %s", data);
  87. const callback = packet => {
  88. // if its the first message we consider the transport open
  89. if ("opening" === this.readyState && packet.type === "open") {
  90. this.onOpen();
  91. }
  92. // if its a close packet, we close the ongoing requests
  93. if ("close" === packet.type) {
  94. this.onClose();
  95. return false;
  96. }
  97. // otherwise bypass onData and handle the message
  98. this.onPacket(packet);
  99. };
  100. // decode payload
  101. (0, engine_io_parser_1.decodePayload)(data, this.socket.binaryType).forEach(callback);
  102. // if an event did not trigger closing
  103. if ("closed" !== this.readyState) {
  104. // if we got data we're not polling
  105. this.polling = false;
  106. this.emit("pollComplete");
  107. if ("open" === this.readyState) {
  108. this.poll();
  109. }
  110. else {
  111. debug('ignoring poll - transport state "%s"', this.readyState);
  112. }
  113. }
  114. }
  115. /**
  116. * For polling, send a close packet.
  117. *
  118. * @api private
  119. */
  120. doClose() {
  121. const close = () => {
  122. debug("writing close packet");
  123. this.write([{ type: "close" }]);
  124. };
  125. if ("open" === this.readyState) {
  126. debug("transport open - closing");
  127. close();
  128. }
  129. else {
  130. // in case we're trying to close while
  131. // handshaking is in progress (GH-164)
  132. debug("transport not open - deferring close");
  133. this.once("open", close);
  134. }
  135. }
  136. /**
  137. * Writes a packets payload.
  138. *
  139. * @param {Array} data packets
  140. * @param {Function} drain callback
  141. * @api private
  142. */
  143. write(packets) {
  144. this.writable = false;
  145. (0, engine_io_parser_1.encodePayload)(packets, data => {
  146. this.doWrite(data, () => {
  147. this.writable = true;
  148. this.emit("drain");
  149. });
  150. });
  151. }
  152. /**
  153. * Generates uri for connection.
  154. *
  155. * @api private
  156. */
  157. uri() {
  158. let query = this.query || {};
  159. const schema = this.opts.secure ? "https" : "http";
  160. let port = "";
  161. // cache busting is forced
  162. if (false !== this.opts.timestampRequests) {
  163. query[this.opts.timestampParam] = (0, yeast_1.default)();
  164. }
  165. if (!this.supportsBinary && !query.sid) {
  166. query.b64 = 1;
  167. }
  168. // avoid port if default for schema
  169. if (this.opts.port &&
  170. (("https" === schema && Number(this.opts.port) !== 443) ||
  171. ("http" === schema && Number(this.opts.port) !== 80))) {
  172. port = ":" + this.opts.port;
  173. }
  174. const encodedQuery = parseqs_1.default.encode(query);
  175. const ipv6 = this.opts.hostname.indexOf(":") !== -1;
  176. return (schema +
  177. "://" +
  178. (ipv6 ? "[" + this.opts.hostname + "]" : this.opts.hostname) +
  179. port +
  180. this.opts.path +
  181. (encodedQuery.length ? "?" + encodedQuery : ""));
  182. }
  183. }
  184. exports.Polling = Polling;