123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984 |
- "use strict";
- var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
- };
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.Socket = exports.RESERVED_EVENTS = void 0;
- const socket_io_parser_1 = require("socket.io-parser");
- const debug_1 = __importDefault(require("debug"));
- const typed_events_1 = require("./typed-events");
- const base64id_1 = __importDefault(require("base64id"));
- const broadcast_operator_1 = require("./broadcast-operator");
- const debug = (0, debug_1.default)("socket.io:socket");
- const RECOVERABLE_DISCONNECT_REASONS = new Set([
- "transport error",
- "transport close",
- "forced close",
- "ping timeout",
- "server shutting down",
- "forced server close",
- ]);
- exports.RESERVED_EVENTS = new Set([
- "connect",
- "connect_error",
- "disconnect",
- "disconnecting",
- "newListener",
- "removeListener",
- ]);
- function noop() { }
- class Socket extends typed_events_1.StrictEventEmitter {
-
- constructor(nsp, client, auth, previousSession) {
- super();
- this.nsp = nsp;
- this.client = client;
-
- this.recovered = false;
-
- this.data = {};
-
- this.connected = false;
- this.acks = new Map();
- this.fns = [];
- this.flags = {};
- this.server = nsp.server;
- this.adapter = this.nsp.adapter;
- if (previousSession) {
- this.id = previousSession.sid;
- this.pid = previousSession.pid;
- previousSession.rooms.forEach((room) => this.join(room));
- this.data = previousSession.data;
- previousSession.missedPackets.forEach((packet) => {
- this.packet({
- type: socket_io_parser_1.PacketType.EVENT,
- data: packet,
- });
- });
- this.recovered = true;
- }
- else {
- if (client.conn.protocol === 3) {
-
- this.id = nsp.name !== "/" ? nsp.name + "#" + client.id : client.id;
- }
- else {
- this.id = base64id_1.default.generateId();
- }
- if (this.server._opts.connectionStateRecovery) {
- this.pid = base64id_1.default.generateId();
- }
- }
- this.handshake = this.buildHandshake(auth);
-
- this.on("error", noop);
- }
-
- buildHandshake(auth) {
- var _a, _b, _c, _d;
- return {
- headers: ((_a = this.request) === null || _a === void 0 ? void 0 : _a.headers) || {},
- time: new Date() + "",
- address: this.conn.remoteAddress,
- xdomain: !!((_b = this.request) === null || _b === void 0 ? void 0 : _b.headers.origin),
-
- secure: !this.request || !!this.request.connection.encrypted,
- issued: +new Date(),
- url: (_c = this.request) === null || _c === void 0 ? void 0 : _c.url,
-
- query: ((_d = this.request) === null || _d === void 0 ? void 0 : _d._query) || {},
- auth,
- };
- }
-
- emit(ev, ...args) {
- if (exports.RESERVED_EVENTS.has(ev)) {
- throw new Error(`"${String(ev)}" is a reserved event name`);
- }
- const data = [ev, ...args];
- const packet = {
- type: socket_io_parser_1.PacketType.EVENT,
- data: data,
- };
-
- if (typeof data[data.length - 1] === "function") {
- const id = this.nsp._ids++;
- debug("emitting packet with ack id %d", id);
- this.registerAckCallback(id, data.pop());
- packet.id = id;
- }
- const flags = Object.assign({}, this.flags);
- this.flags = {};
-
- if (this.nsp.server.opts.connectionStateRecovery) {
-
- this.adapter.broadcast(packet, {
- rooms: new Set([this.id]),
- except: new Set(),
- flags,
- });
- }
- else {
- this.notifyOutgoingListeners(packet);
- this.packet(packet, flags);
- }
- return true;
- }
-
- emitWithAck(ev, ...args) {
-
- const withErr = this.flags.timeout !== undefined;
- return new Promise((resolve, reject) => {
- args.push((arg1, arg2) => {
- if (withErr) {
- return arg1 ? reject(arg1) : resolve(arg2);
- }
- else {
- return resolve(arg1);
- }
- });
- this.emit(ev, ...args);
- });
- }
-
- registerAckCallback(id, ack) {
- const timeout = this.flags.timeout;
- if (timeout === undefined) {
- this.acks.set(id, ack);
- return;
- }
- const timer = setTimeout(() => {
- debug("event with ack id %d has timed out after %d ms", id, timeout);
- this.acks.delete(id);
- ack.call(this, new Error("operation has timed out"));
- }, timeout);
- this.acks.set(id, (...args) => {
- clearTimeout(timer);
- ack.apply(this, [null, ...args]);
- });
- }
-
- to(room) {
- return this.newBroadcastOperator().to(room);
- }
-
- in(room) {
- return this.newBroadcastOperator().in(room);
- }
-
- except(room) {
- return this.newBroadcastOperator().except(room);
- }
-
- send(...args) {
- this.emit("message", ...args);
- return this;
- }
-
- write(...args) {
- this.emit("message", ...args);
- return this;
- }
-
- packet(packet, opts = {}) {
- packet.nsp = this.nsp.name;
- opts.compress = false !== opts.compress;
- this.client._packet(packet, opts);
- }
-
- join(rooms) {
- debug("join room %s", rooms);
- return this.adapter.addAll(this.id, new Set(Array.isArray(rooms) ? rooms : [rooms]));
- }
-
- leave(room) {
- debug("leave room %s", room);
- return this.adapter.del(this.id, room);
- }
-
- leaveAll() {
- this.adapter.delAll(this.id);
- }
-
- _onconnect() {
- debug("socket connected - writing packet");
- this.connected = true;
- this.join(this.id);
- if (this.conn.protocol === 3) {
- this.packet({ type: socket_io_parser_1.PacketType.CONNECT });
- }
- else {
- this.packet({
- type: socket_io_parser_1.PacketType.CONNECT,
- data: { sid: this.id, pid: this.pid },
- });
- }
- }
-
- _onpacket(packet) {
- debug("got packet %j", packet);
- switch (packet.type) {
- case socket_io_parser_1.PacketType.EVENT:
- this.onevent(packet);
- break;
- case socket_io_parser_1.PacketType.BINARY_EVENT:
- this.onevent(packet);
- break;
- case socket_io_parser_1.PacketType.ACK:
- this.onack(packet);
- break;
- case socket_io_parser_1.PacketType.BINARY_ACK:
- this.onack(packet);
- break;
- case socket_io_parser_1.PacketType.DISCONNECT:
- this.ondisconnect();
- break;
- }
- }
-
- onevent(packet) {
- const args = packet.data || [];
- debug("emitting event %j", args);
- if (null != packet.id) {
- debug("attaching ack callback to event");
- args.push(this.ack(packet.id));
- }
- if (this._anyListeners && this._anyListeners.length) {
- const listeners = this._anyListeners.slice();
- for (const listener of listeners) {
- listener.apply(this, args);
- }
- }
- this.dispatch(args);
- }
-
- ack(id) {
- const self = this;
- let sent = false;
- return function () {
-
- if (sent)
- return;
- const args = Array.prototype.slice.call(arguments);
- debug("sending ack %j", args);
- self.packet({
- id: id,
- type: socket_io_parser_1.PacketType.ACK,
- data: args,
- });
- sent = true;
- };
- }
-
- onack(packet) {
- const ack = this.acks.get(packet.id);
- if ("function" == typeof ack) {
- debug("calling ack %s with %j", packet.id, packet.data);
- ack.apply(this, packet.data);
- this.acks.delete(packet.id);
- }
- else {
- debug("bad ack %s", packet.id);
- }
- }
-
- ondisconnect() {
- debug("got disconnect packet");
- this._onclose("client namespace disconnect");
- }
-
- _onerror(err) {
-
-
-
-
- this.emitReserved("error", err);
- }
-
- _onclose(reason, description) {
- if (!this.connected)
- return this;
- debug("closing socket - reason %s", reason);
- this.emitReserved("disconnecting", reason, description);
- if (this.server._opts.connectionStateRecovery &&
- RECOVERABLE_DISCONNECT_REASONS.has(reason)) {
- debug("connection state recovery is enabled for sid %s", this.id);
- this.adapter.persistSession({
- sid: this.id,
- pid: this.pid,
- rooms: [...this.rooms],
- data: this.data,
- });
- }
- this._cleanup();
- this.client._remove(this);
- this.connected = false;
- this.emitReserved("disconnect", reason, description);
- return;
- }
-
- _cleanup() {
- this.leaveAll();
- this.nsp._remove(this);
- this.join = noop;
- }
-
- _error(err) {
- this.packet({ type: socket_io_parser_1.PacketType.CONNECT_ERROR, data: err });
- }
-
- disconnect(close = false) {
- if (!this.connected)
- return this;
- if (close) {
- this.client._disconnect();
- }
- else {
- this.packet({ type: socket_io_parser_1.PacketType.DISCONNECT });
- this._onclose("server namespace disconnect");
- }
- return this;
- }
-
- compress(compress) {
- this.flags.compress = compress;
- return this;
- }
-
- get volatile() {
- this.flags.volatile = true;
- return this;
- }
-
- get broadcast() {
- return this.newBroadcastOperator();
- }
-
- get local() {
- return this.newBroadcastOperator().local;
- }
-
- timeout(timeout) {
- this.flags.timeout = timeout;
- return this;
- }
-
- dispatch(event) {
- debug("dispatching an event %j", event);
- this.run(event, (err) => {
- process.nextTick(() => {
- if (err) {
- return this._onerror(err);
- }
- if (this.connected) {
- super.emitUntyped.apply(this, event);
- }
- else {
- debug("ignore packet received after disconnection");
- }
- });
- });
- }
-
- use(fn) {
- this.fns.push(fn);
- return this;
- }
-
- run(event, fn) {
- const fns = this.fns.slice(0);
- if (!fns.length)
- return fn(null);
- function run(i) {
- fns[i](event, function (err) {
-
- if (err)
- return fn(err);
-
- if (!fns[i + 1])
- return fn(null);
-
- run(i + 1);
- });
- }
- run(0);
- }
-
- get disconnected() {
- return !this.connected;
- }
-
- get request() {
- return this.client.request;
- }
-
- get conn() {
- return this.client.conn;
- }
-
- get rooms() {
- return this.adapter.socketRooms(this.id) || new Set();
- }
-
- onAny(listener) {
- this._anyListeners = this._anyListeners || [];
- this._anyListeners.push(listener);
- return this;
- }
-
- prependAny(listener) {
- this._anyListeners = this._anyListeners || [];
- this._anyListeners.unshift(listener);
- return this;
- }
-
- offAny(listener) {
- if (!this._anyListeners) {
- return this;
- }
- if (listener) {
- const listeners = this._anyListeners;
- for (let i = 0; i < listeners.length; i++) {
- if (listener === listeners[i]) {
- listeners.splice(i, 1);
- return this;
- }
- }
- }
- else {
- this._anyListeners = [];
- }
- return this;
- }
-
- listenersAny() {
- return this._anyListeners || [];
- }
-
- onAnyOutgoing(listener) {
- this._anyOutgoingListeners = this._anyOutgoingListeners || [];
- this._anyOutgoingListeners.push(listener);
- return this;
- }
-
- prependAnyOutgoing(listener) {
- this._anyOutgoingListeners = this._anyOutgoingListeners || [];
- this._anyOutgoingListeners.unshift(listener);
- return this;
- }
-
- offAnyOutgoing(listener) {
- if (!this._anyOutgoingListeners) {
- return this;
- }
- if (listener) {
- const listeners = this._anyOutgoingListeners;
- for (let i = 0; i < listeners.length; i++) {
- if (listener === listeners[i]) {
- listeners.splice(i, 1);
- return this;
- }
- }
- }
- else {
- this._anyOutgoingListeners = [];
- }
- return this;
- }
-
- listenersAnyOutgoing() {
- return this._anyOutgoingListeners || [];
- }
-
- notifyOutgoingListeners(packet) {
- if (this._anyOutgoingListeners && this._anyOutgoingListeners.length) {
- const listeners = this._anyOutgoingListeners.slice();
- for (const listener of listeners) {
- listener.apply(this, packet.data);
- }
- }
- }
- newBroadcastOperator() {
- const flags = Object.assign({}, this.flags);
- this.flags = {};
- return new broadcast_operator_1.BroadcastOperator(this.adapter, new Set(), new Set([this.id]), flags);
- }
- }
- exports.Socket = Socket;
|