A bot used for https://code-your-snake.codingmaster398.repl.co/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
6.9 KiB
198 lines
6.9 KiB
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.WS = void 0;
|
|
const transport_js_1 = require("../transport.js");
|
|
const parseqs_js_1 = require("../contrib/parseqs.js");
|
|
const yeast_js_1 = require("../contrib/yeast.js");
|
|
const util_js_1 = require("../util.js");
|
|
const websocket_constructor_js_1 = require("./websocket-constructor.js");
|
|
const debug_1 = __importDefault(require("debug")); // debug()
|
|
const engine_io_parser_1 = require("engine.io-parser");
|
|
const debug = (0, debug_1.default)("engine.io-client:websocket"); // debug()
|
|
// detect ReactNative environment
|
|
const isReactNative = typeof navigator !== "undefined" &&
|
|
typeof navigator.product === "string" &&
|
|
navigator.product.toLowerCase() === "reactnative";
|
|
class WS extends transport_js_1.Transport {
|
|
/**
|
|
* WebSocket transport constructor.
|
|
*
|
|
* @api {Object} connection options
|
|
* @api public
|
|
*/
|
|
constructor(opts) {
|
|
super(opts);
|
|
this.supportsBinary = !opts.forceBase64;
|
|
}
|
|
/**
|
|
* Transport name.
|
|
*
|
|
* @api public
|
|
*/
|
|
get name() {
|
|
return "websocket";
|
|
}
|
|
/**
|
|
* Opens socket.
|
|
*
|
|
* @api private
|
|
*/
|
|
doOpen() {
|
|
if (!this.check()) {
|
|
// let probe timeout
|
|
return;
|
|
}
|
|
const uri = this.uri();
|
|
const protocols = this.opts.protocols;
|
|
// React Native only supports the 'headers' option, and will print a warning if anything else is passed
|
|
const opts = isReactNative
|
|
? {}
|
|
: (0, util_js_1.pick)(this.opts, "agent", "perMessageDeflate", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "localAddress", "protocolVersion", "origin", "maxPayload", "family", "checkServerIdentity");
|
|
if (this.opts.extraHeaders) {
|
|
opts.headers = this.opts.extraHeaders;
|
|
}
|
|
try {
|
|
this.ws =
|
|
websocket_constructor_js_1.usingBrowserWebSocket && !isReactNative
|
|
? protocols
|
|
? new websocket_constructor_js_1.WebSocket(uri, protocols)
|
|
: new websocket_constructor_js_1.WebSocket(uri)
|
|
: new websocket_constructor_js_1.WebSocket(uri, protocols, opts);
|
|
}
|
|
catch (err) {
|
|
return this.emitReserved("error", err);
|
|
}
|
|
this.ws.binaryType = this.socket.binaryType || websocket_constructor_js_1.defaultBinaryType;
|
|
this.addEventListeners();
|
|
}
|
|
/**
|
|
* Adds event listeners to the socket
|
|
*
|
|
* @api private
|
|
*/
|
|
addEventListeners() {
|
|
this.ws.onopen = () => {
|
|
if (this.opts.autoUnref) {
|
|
this.ws._socket.unref();
|
|
}
|
|
this.onOpen();
|
|
};
|
|
this.ws.onclose = closeEvent => this.onClose({
|
|
description: "websocket connection closed",
|
|
context: closeEvent
|
|
});
|
|
this.ws.onmessage = ev => this.onData(ev.data);
|
|
this.ws.onerror = e => this.onError("websocket error", e);
|
|
}
|
|
/**
|
|
* Writes data to socket.
|
|
*
|
|
* @param {Array} array of packets.
|
|
* @api private
|
|
*/
|
|
write(packets) {
|
|
this.writable = false;
|
|
// encodePacket efficient as it uses WS framing
|
|
// no need for encodePayload
|
|
for (let i = 0; i < packets.length; i++) {
|
|
const packet = packets[i];
|
|
const lastPacket = i === packets.length - 1;
|
|
(0, engine_io_parser_1.encodePacket)(packet, this.supportsBinary, data => {
|
|
// always create a new object (GH-437)
|
|
const opts = {};
|
|
if (!websocket_constructor_js_1.usingBrowserWebSocket) {
|
|
if (packet.options) {
|
|
opts.compress = packet.options.compress;
|
|
}
|
|
if (this.opts.perMessageDeflate) {
|
|
const len =
|
|
// @ts-ignore
|
|
"string" === typeof data ? Buffer.byteLength(data) : data.length;
|
|
if (len < this.opts.perMessageDeflate.threshold) {
|
|
opts.compress = false;
|
|
}
|
|
}
|
|
}
|
|
// Sometimes the websocket has already been closed but the browser didn't
|
|
// have a chance of informing us about it yet, in that case send will
|
|
// throw an error
|
|
try {
|
|
if (websocket_constructor_js_1.usingBrowserWebSocket) {
|
|
// TypeError is thrown when passing the second argument on Safari
|
|
this.ws.send(data);
|
|
}
|
|
else {
|
|
this.ws.send(data, opts);
|
|
}
|
|
}
|
|
catch (e) {
|
|
debug("websocket closed before onclose event");
|
|
}
|
|
if (lastPacket) {
|
|
// fake drain
|
|
// defer to next tick to allow Socket to clear writeBuffer
|
|
(0, websocket_constructor_js_1.nextTick)(() => {
|
|
this.writable = true;
|
|
this.emitReserved("drain");
|
|
}, this.setTimeoutFn);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
/**
|
|
* Closes socket.
|
|
*
|
|
* @api private
|
|
*/
|
|
doClose() {
|
|
if (typeof this.ws !== "undefined") {
|
|
this.ws.close();
|
|
this.ws = null;
|
|
}
|
|
}
|
|
/**
|
|
* Generates uri for connection.
|
|
*
|
|
* @api private
|
|
*/
|
|
uri() {
|
|
let query = this.query || {};
|
|
const schema = this.opts.secure ? "wss" : "ws";
|
|
let port = "";
|
|
// avoid port if default for schema
|
|
if (this.opts.port &&
|
|
(("wss" === schema && Number(this.opts.port) !== 443) ||
|
|
("ws" === schema && Number(this.opts.port) !== 80))) {
|
|
port = ":" + this.opts.port;
|
|
}
|
|
// append timestamp to URI
|
|
if (this.opts.timestampRequests) {
|
|
query[this.opts.timestampParam] = (0, yeast_js_1.yeast)();
|
|
}
|
|
// communicate binary support capabilities
|
|
if (!this.supportsBinary) {
|
|
query.b64 = 1;
|
|
}
|
|
const encodedQuery = (0, parseqs_js_1.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 : ""));
|
|
}
|
|
/**
|
|
* Feature detection for WebSocket.
|
|
*
|
|
* @return {Boolean} whether this transport is available.
|
|
* @api public
|
|
*/
|
|
check() {
|
|
return !!websocket_constructor_js_1.WebSocket;
|
|
}
|
|
}
|
|
exports.WS = WS;
|
|
|