Skip to content

Commit

Permalink
fix: prevent duplicate connections when multiplexing
Browse files Browse the repository at this point in the history
This bug was introduced in [1]: a multiplexed socket could in some
cases send multiple CONNECT packets, resulting in duplicate connections
on the server side.

A cached socket will now be reopened only if it was inactive, that is,
if one had explicitly called socket.disconnect() before.

Related: #1460

[1]: b7dd891
  • Loading branch information
darrachequesne committed Feb 20, 2023
1 parent 4996f9e commit 46213a6
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 3 deletions.
4 changes: 1 addition & 3 deletions lib/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -465,9 +465,7 @@ export class Manager<
if (!socket) {
socket = new Socket(this, nsp, opts);
this.nsps[nsp] = socket;
}

if (this._autoConnect) {
} else if (this._autoConnect && !socket.active) {
socket.connect();
}

Expand Down
53 changes: 53 additions & 0 deletions test/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -838,4 +838,57 @@ describe("connection", () => {
});
});
});

it("should not reopen a cached but active socket", () => {
return wrap((done) => {
const manager = new Manager(BASE_URL, {
autoConnect: true,
});

let i = 0;
const expected = ["0", "1"];

manager.engine.on("packetCreate", ({ data }) => {
expect(data).to.eql(expected[i++]);
});

manager.once("open", () => {
const socket = manager.socket("/");
const socket2 = manager.socket("/");

expect(socket2 === socket).to.be(true);

socket.on("connect", () => {
socket.disconnect();
done();
});
});
});
});

it("should not reopen an already active socket", () => {
return wrap((done) => {
const manager = new Manager(BASE_URL, {
autoConnect: true,
});

let i = 0;
const expected = ["0", "0/foo,", "1", "1/foo,"];

manager.engine.on("packetCreate", ({ data }) => {
expect(data).to.eql(expected[i++]);
});

manager.once("open", () => {
const socket = manager.socket("/");
const socketFoo = manager.socket("/foo");

socket.on("connect", () => {
socket.disconnect();
socketFoo.disconnect();
done();
});
});
});
});
});

0 comments on commit 46213a6

Please sign in to comment.