Skip to content

socket.join could lead to a room leak. #4380

@baptistejamin

Description

@baptistejamin

Describe the bug

We are using socket io since years now, and we discovered a very weird bug that can occur under some conditions.

It seems it's possible to join rooms using the base adapter, even if the socket is destroyed or disconnected. I don't know if it was intended initially, but adapter.addAll shouldn't be connected if the socket is no longer available.

A such issue could appear for instance under an elevated database latency. If the client socket disconnected before the socket.join action, the join action is performed anyway.

To Reproduce

  1. Use the client
  2. Leave the page before 15s

Run those steps 5 times.

DUMMY_ROOM should have 5 different sockets attached to the rooms, even if those sockets are no longer connected.

Please fill the following code example:

Socket.IO server version: any version

Server

import { Server } from "socket.io";

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

io.on("connection", (socket) => {
  socket.on("ping", () => {
    // Simulate a database latency
    new Promise((resolve) => {
      setTimeout(resolve, 15000);
    })
    .then(() => {
      socket.join("DUMMY_ROOM");
    });
  })

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

Socket.IO client version: x.y.z

Client

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

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

socket.on("connect", () => {
  socket.emit("ping")
});

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

Expected behavior

socket.join shouldn't propagate this.adapter.addAll if the socket no longer exists.

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