Skip to content

Commit 518f534

Browse files
fix(server): send events once the handshake is completed
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
1 parent 0016c25 commit 518f534

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

packages/socket.io/lib/socket.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ export class Socket<
144144
#anyIncomingListeners?: Array<(...args: Event) => void>;
145145
#anyOutgoingListeners?: Array<(...args: Event) => void>;
146146

147+
#preConnectBuffer: Packet[] = [];
148+
147149
/* private */ readonly client: Client<
148150
ListenEvents,
149151
EmitEvents,
@@ -197,8 +199,12 @@ export class Socket<
197199
const flags = Object.assign({}, this.flags);
198200
this.flags = {};
199201

200-
this._notifyOutgoingListeners(packet.data);
201-
this.packet(packet, flags);
202+
if (this.connected) {
203+
this._notifyOutgoingListeners(packet.data);
204+
this.packet(packet, flags);
205+
} else {
206+
this.#preConnectBuffer.push(packet);
207+
}
202208

203209
return true;
204210
}
@@ -514,6 +520,11 @@ export class Socket<
514520
this.connected = true;
515521
this.join(this.id);
516522
this.packet({ type: PacketType.CONNECT, data: { sid: this.id } });
523+
this.#preConnectBuffer.forEach((packet) => {
524+
this._notifyOutgoingListeners(packet.data);
525+
this.packet(packet);
526+
});
527+
this.#preConnectBuffer = [];
517528
}
518529

519530
/**

packages/socket.io/test/handshake.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
eioPush,
1111
enableLogs,
1212
parseSessionID,
13+
runHandshake,
1314
} from "../../util.test.ts";
1415
import { setup } from "./setup.test.ts";
1516

@@ -236,4 +237,30 @@ describe("handshake", () => {
236237
},
237238
);
238239
});
240+
241+
it("should complete handshake before sending any event", () => {
242+
const io = new Server();
243+
244+
return setup(
245+
io,
246+
1,
247+
async (port, done) => {
248+
io.use((socket) => {
249+
socket.emit("1");
250+
io.emit("ignored"); // socket is not connected yet
251+
return Promise.resolve();
252+
});
253+
254+
io.on("connection", (socket) => {
255+
socket.emit("2");
256+
});
257+
258+
const [_, firstPacket] = await runHandshake(port);
259+
260+
assertEquals(firstPacket, '42["1"]\x1e42["2"]');
261+
262+
done();
263+
},
264+
);
265+
});
239266
});

0 commit comments

Comments
 (0)