socket.io icon indicating copy to clipboard operation
socket.io copied to clipboard

Events before disconnection dropped

Open asideofcode-dev opened this issue 1 year ago • 7 comments

Describe the bug
In a Socket.IO application, events emitted just before a client disconnects are not properly handled by specific on(...) listeners. While the onAny(...) listener detects these events, the specific on(...) listeners do not. This issue occurs with any event emitted just before disconnection. The reason onAny(...) works is that it runs before the dispatch, which relies on process.nextTick.

To Reproduce

Socket.IO server version: 4.x.x (replace with your version)

Server

import { Server } from "socket.io";

const io = new Server(3000, {});

io.on("connection", (socket) => {
  console.log(`connect ${socket.id}`);

  // Example event listener (applies to any event)
  socket.on("exampleEvent", () => {
    console.log(`exampleEvent received before disconnect ${socket.id}`);
  });

  // Using onAny listener
  socket.onAny((event, ...args) => {
    console.log(`onAny received ${event} before disconnect ${socket.id}`);
  });

  socket.on("disconnect", () => {
    console.log(`disconnect ${socket.id}`);
  });
});

Socket.IO client version: 4.x.x (replace with your version)

Client

import { io } from "socket.io-client";

const socket = io("ws://localhost:3000/", {});

socket.on("connect", () => {
  console.log(`connect ${socket.id}`);
  
  // Emit any event just before disconnecting
  socket.emit("exampleEvent");
  socket.disconnect();
});

socket.on("disconnect", () => {
  console.log("disconnect");
});

Expected behavior
The on listener for any event (e.g., exampleEvent) should detect and handle the event before disconnection. Currently, the onAny listener detects the event, but the specific on(...) listener does not. This occurs because onAny runs before the dispatch, which relies on process.nextTick, allowing it to detect the event before disconnection, see https://github.com/socketio/socket.io/blob/175a2c58c1bc37eb9b87f87df47e1f9388b01d55/packages/socket.io/lib/socket.ts#L559-L575.

Platform:

Not relevant

Additional context
This issue affects any event emitted just before disconnection. The onAny listener works because it operates before the event dispatch process, which uses process.nextTick. As a result, events are detected by onAny but missed by the specific on(...) listeners, which rely on the dispatch mechanism that happens after disconnection begins.

asideofcode-dev avatar Oct 20 '24 00:10 asideofcode-dev