"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Polling = void 0; const transport_js_1 = require("../transport.js"); const debug_1 = __importDefault(require("debug")); // debug() const yeast_1 = __importDefault(require("yeast")); const parseqs_1 = __importDefault(require("parseqs")); const engine_io_parser_1 = require("engine.io-parser"); const debug = (0, debug_1.default)("engine.io-client:polling"); // debug() class Polling extends transport_js_1.Transport { constructor() { super(...arguments); this.polling = false; } /** * Transport name. */ get name() { return "polling"; } /** * Opens the socket (triggers polling). We write a PING message to determine * when the transport is open. * * @api private */ doOpen() { this.poll(); } /** * Pauses polling. * * @param {Function} callback upon buffers are flushed and transport is paused * @api private */ pause(onPause) { this.readyState = "pausing"; const pause = () => { debug("paused"); this.readyState = "paused"; onPause(); }; if (this.polling || !this.writable) { let total = 0; if (this.polling) { debug("we are currently polling - waiting to pause"); total++; this.once("pollComplete", function () { debug("pre-pause polling complete"); --total || pause(); }); } if (!this.writable) { debug("we are currently writing - waiting to pause"); total++; this.once("drain", function () { debug("pre-pause writing complete"); --total || pause(); }); } } else { pause(); } } /** * Starts polling cycle. * * @api public */ poll() { debug("polling"); this.polling = true; this.doPoll(); this.emit("poll"); } /** * Overloads onData to detect payloads. * * @api private */ onData(data) { debug("polling got data %s", data); const callback = packet => { // if its the first message we consider the transport open if ("opening" === this.readyState && packet.type === "open") { this.onOpen(); } // if its a close packet, we close the ongoing requests if ("close" === packet.type) { this.onClose(); return false; } // otherwise bypass onData and handle the message this.onPacket(packet); }; // decode payload (0, engine_io_parser_1.decodePayload)(data, this.socket.binaryType).forEach(callback); // if an event did not trigger closing if ("closed" !== this.readyState) { // if we got data we're not polling this.polling = false; this.emit("pollComplete"); if ("open" === this.readyState) { this.poll(); } else { debug('ignoring poll - transport state "%s"', this.readyState); } } } /** * For polling, send a close packet. * * @api private */ doClose() { const close = () => { debug("writing close packet"); this.write([{ type: "close" }]); }; if ("open" === this.readyState) { debug("transport open - closing"); close(); } else { // in case we're trying to close while // handshaking is in progress (GH-164) debug("transport not open - deferring close"); this.once("open", close); } } /** * Writes a packets payload. * * @param {Array} data packets * @param {Function} drain callback * @api private */ write(packets) { this.writable = false; (0, engine_io_parser_1.encodePayload)(packets, data => { this.doWrite(data, () => { this.writable = true; this.emit("drain"); }); }); } /** * Generates uri for connection. * * @api private */ uri() { let query = this.query || {}; const schema = this.opts.secure ? "https" : "http"; let port = ""; // cache busting is forced if (false !== this.opts.timestampRequests) { query[this.opts.timestampParam] = (0, yeast_1.default)(); } if (!this.supportsBinary && !query.sid) { query.b64 = 1; } // avoid port if default for schema if (this.opts.port && (("https" === schema && Number(this.opts.port) !== 443) || ("http" === schema && Number(this.opts.port) !== 80))) { port = ":" + this.opts.port; } const encodedQuery = parseqs_1.default.encode(query); const ipv6 = this.opts.hostname.indexOf(":") !== -1; return (schema + "://" + (ipv6 ? "[" + this.opts.hostname + "]" : this.opts.hostname) + port + this.opts.path + (encodedQuery.length ? "?" + encodedQuery : "")); } } exports.Polling = Polling;