Skip to content

Disconnect handler not executed if connection drops during middleware execution #4129

@adroste

Description

@adroste

Describe the bug
If I use a middleware (e.g. for authentication) I cannot handle a client disconnect because

  1. disconnect event-handler does not get executed
  2. socket.connected won't update properly (from true to false)

To Reproduce

Please fill the following code example:

Socket.IO server version: 4.2.0

Server

import { Server } from "socket.io";

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

io.use(async (socket, next) => {
    console.log(`middleware`, socket.id);

    // bug 1: disconnect handler will never execute
    socket.on("disconnect", () => {
      console.log(`disconnect ${socket.id}`);
    });
    
    // long running async operation
    // client will disconnect before operation has finished
    await new Promise(resolve => setTimeout(resolve, 3000));

    // bug 2: connected state is still true
    console.log(`still connected: ${socket.connected}`);

    next();
});

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

Socket.IO client version: 4

Client

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

const socket = io("ws://localhost:3000/", {});
// force disconnect before long running operation has finished
setTimeout(window.location.reload, 1000);

Expected behavior
socket.connected will update properly and disconnect event-handler will run

Platform:
node.js 16 on macOS

Additional context
The workaround to the problem is: don't trigger side-effects in middleware and always add custom properties to the socket object to transfer information over to connection event-handler

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions