Skip to content

Commit

Permalink
fix: send volatile packets with binary attachments
Browse files Browse the repository at this point in the history
The binary attachments of volatile packets were discarded (only the
header packet was sent) due to a bug introduced by [1].

Related: #3919

[1]: dc381b7
  • Loading branch information
darrachequesne committed Sep 9, 2021
1 parent c100b7b commit dc81fcf
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
13 changes: 8 additions & 5 deletions lib/client.ts
Expand Up @@ -209,13 +209,11 @@ export class Client<
const encodedPackets = opts.preEncoded
? (packet as any[]) // previous versions of the adapter incorrectly used socket.packet() instead of writeToEngine()
: this.encoder.encode(packet as Packet);
for (const encodedPacket of encodedPackets) {
this.writeToEngine(encodedPacket, opts);
}
this.writeToEngine(encodedPackets, opts);
}

private writeToEngine(
encodedPacket: String | Buffer,
encodedPackets: Array<String | Buffer>,
opts: WriteOptions
): void {
if (opts.volatile && !this.conn.transport.writable) {
Expand All @@ -224,7 +222,12 @@ export class Client<
);
return;
}
this.conn.write(encodedPacket, opts);
const packets = Array.isArray(encodedPackets)
? encodedPackets
: [encodedPackets];
for (const encodedPacket of packets) {
this.conn.write(encodedPacket, opts);
}
}

/**
Expand Down
26 changes: 26 additions & 0 deletions test/socket.io.ts
Expand Up @@ -1382,6 +1382,32 @@ describe("socket.io", () => {
}, 200);
});

it("should emit only one consecutive volatile event with binary (ws)", (done) => {
const srv = createServer();
const sio = new Server(srv, { transports: ["websocket"] });

let counter = 0;
srv.listen(() => {
sio.on("connection", (s) => {
// Wait to make sure there are no packets being sent for opening the connection
setTimeout(() => {
s.volatile.emit("ev", Buffer.from([1, 2, 3]));
s.volatile.emit("ev", Buffer.from([4, 5, 6]));
}, 20);
});

const socket = client(srv, { transports: ["websocket"] });
socket.on("ev", () => {
counter++;
});
});

setTimeout(() => {
expect(counter).to.be(1);
done();
}, 200);
});

it("should emit regular events after trying a failed volatile event (polling)", (done) => {
const srv = createServer();
const sio = new Server(srv, { transports: ["polling"] });
Expand Down

0 comments on commit dc81fcf

Please sign in to comment.