Skip to content

Commit

Permalink
fix(server): send events once the handshake is completed
Browse files Browse the repository at this point in the history
Before that change, an event which was emitted in a middleware (before
the socket is considered connected) was sent before the CONNECT packet,
which is a bit weird.

Note: this explains why the Node.js client implementation has a buffer
there [1]

[1]: https://github.com/socketio/socket.io-client/blob/2d708137298784761763fdebbd64785819527f45/lib/socket.ts#L68
  • Loading branch information
darrachequesne committed Oct 10, 2022
1 parent 0016c25 commit 518f534
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
15 changes: 13 additions & 2 deletions packages/socket.io/lib/socket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ export class Socket<
#anyIncomingListeners?: Array<(...args: Event) => void>;
#anyOutgoingListeners?: Array<(...args: Event) => void>;

#preConnectBuffer: Packet[] = [];

/* private */ readonly client: Client<
ListenEvents,
EmitEvents,
Expand Down Expand Up @@ -197,8 +199,12 @@ export class Socket<
const flags = Object.assign({}, this.flags);
this.flags = {};

this._notifyOutgoingListeners(packet.data);
this.packet(packet, flags);
if (this.connected) {
this._notifyOutgoingListeners(packet.data);
this.packet(packet, flags);
} else {
this.#preConnectBuffer.push(packet);
}

return true;
}
Expand Down Expand Up @@ -514,6 +520,11 @@ export class Socket<
this.connected = true;
this.join(this.id);
this.packet({ type: PacketType.CONNECT, data: { sid: this.id } });
this.#preConnectBuffer.forEach((packet) => {
this._notifyOutgoingListeners(packet.data);
this.packet(packet);
});
this.#preConnectBuffer = [];
}

/**
Expand Down
27 changes: 27 additions & 0 deletions packages/socket.io/test/handshake.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
eioPush,
enableLogs,
parseSessionID,
runHandshake,
} from "../../util.test.ts";
import { setup } from "./setup.test.ts";

Expand Down Expand Up @@ -236,4 +237,30 @@ describe("handshake", () => {
},
);
});

it("should complete handshake before sending any event", () => {
const io = new Server();

return setup(
io,
1,
async (port, done) => {
io.use((socket) => {
socket.emit("1");
io.emit("ignored"); // socket is not connected yet
return Promise.resolve();
});

io.on("connection", (socket) => {
socket.emit("2");
});

const [_, firstPacket] = await runHandshake(port);

assertEquals(firstPacket, '42["1"]\x1e42["2"]');

done();
},
);
});
});

0 comments on commit 518f534

Please sign in to comment.