Skip to content

Commit f8f60fc

Browse files
fix: keep track of active sockets
When a given socket was disconnected, either by the server-side or by the client-side, the manager was closed too, regardless of the other connected sockets. ```js const socket1 = io({ autoConnect: false }); const socket2 = io("/test"); socket1.disconnect(); // also disconnect socket2 ``` This bug was introduced in [1]. [1]: b60e909
1 parent ec1f8c3 commit f8f60fc

File tree

3 files changed

+45
-17
lines changed

3 files changed

+45
-17
lines changed

lib/manager.ts

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,6 @@ export class Manager extends Emitter {
292292
private _reconnectionDelayMax: number;
293293
private _timeout: any;
294294

295-
private connecting: Array<Socket> = [];
296295
private encoder: Encoder;
297296
private decoder: Decoder;
298297
private skipReconnect: boolean;
@@ -601,19 +600,6 @@ export class Manager extends Emitter {
601600
if (!socket) {
602601
socket = new Socket(this, nsp, opts);
603602
this.nsps[nsp] = socket;
604-
var self = this;
605-
socket.on("connecting", onConnecting);
606-
607-
if (this._autoConnect) {
608-
// manually call here since connecting event is fired before listening
609-
onConnecting();
610-
}
611-
}
612-
613-
function onConnecting() {
614-
if (!~self.connecting.indexOf(socket)) {
615-
self.connecting.push(socket);
616-
}
617603
}
618604

619605
return socket;
@@ -626,9 +612,16 @@ export class Manager extends Emitter {
626612
* @private
627613
*/
628614
_destroy(socket: Socket) {
629-
const index = this.connecting.indexOf(socket);
630-
if (~index) this.connecting.splice(index, 1);
631-
if (this.connecting.length) return;
615+
const nsps = Object.keys(this.nsps);
616+
617+
for (const nsp of nsps) {
618+
const socket = this.nsps[nsp];
619+
620+
if (socket.active) {
621+
debug("socket %s is still active, skipping close", nsp);
622+
return;
623+
}
624+
}
632625

633626
this._close();
634627
}

lib/socket.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,13 @@ export class Socket extends Emitter {
8888
];
8989
}
9090

91+
/**
92+
* Whether the Socket will try to reconnect when its Manager connects or reconnects
93+
*/
94+
public get active(): boolean {
95+
return !!this.subs;
96+
}
97+
9198
/**
9299
* "Opens" the socket.
93100
*
@@ -343,6 +350,7 @@ export class Socket extends Emitter {
343350
* @private
344351
*/
345352
private onconnect(id: string) {
353+
debug("socket connected with id %s", id);
346354
this.id = id;
347355
this.connected = true;
348356
this.disconnected = false;

test/connection.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,33 @@ describe("connection", function () {
427427
});
428428
});
429429

430+
it("should not close the connection when disconnecting a single socket", (done) => {
431+
const manager = new Manager({
432+
autoConnect: false,
433+
});
434+
const socket1 = manager.socket("/foo");
435+
const socket2 = manager.socket("/asd");
436+
437+
socket1.connect();
438+
socket1.on("connect", () => {
439+
socket2.connect();
440+
});
441+
442+
socket2.on("connect", () => {
443+
socket2.on("disconnect", () => {
444+
done(new Error("should not happen for now"));
445+
});
446+
socket1.disconnect();
447+
setTimeout(() => {
448+
socket2.off("disconnect");
449+
manager.on("close", () => {
450+
done();
451+
});
452+
socket2.disconnect();
453+
}, 200);
454+
});
455+
});
456+
430457
// Ignore incorrect connection test for old IE due to no support for
431458
// `script.onerror` (see: http://requirejs.org/docs/api.html#ieloadfail)
432459
if (!global.document || hasCORS) {

0 commit comments

Comments
 (0)