Skip to content

Publishing to rooms isn't working after connection recovery with uWebSockets #4810

Closed
@ABE-Mark45

Description

@ABE-Mark45

Describe the bug
I am creating a simple pub-sub system in which I have

  • A socket.io server integrated with uWebSockets and reconnection recovery is enabled
  • A publisher emitting messages periodically to a certain room
  • A subscriber listening to messages sent to this room and closing the connection deliberately periodically

The expected behavior is after reconnection the subscriber should receive the buffered messages at reconnection period and continue receiving newer messages. However, what really happens is that the subscriber only receive the buffered messages and doesn't receive any newer ones. I am using socket.io.engine.close() to deliberately close the connection (same happens if you just close the connection from Chrome Dev Tools. The current weird behavior is whenever it is called, a surge of buffered messages is processed by the client all at once. So it seems that room messages are well-received by the client, but they events are not passed to callbacks for some reason. The sever is working properly if an httpServer is used instead.

To Reproduce
Socket.IO server version: 4.7.2

Server

const { Server } = require("socket.io");
const { App } = require("uWebSockets.js");

const app = new App();
const io = new Server({
  connectionStateRecovery: {
    maxDisconnectionDuration: 2 * 60 * 1000,
    skipMiddlewares: true,
  },
  cors: {
    origin: "*",
  },
});

io.attachApp(app);

io.on("connection", (socket) => {
  if (socket.recovered) {
    console.log("A user recovered", socket.id);
  } else {
    console.log("A user connected");

    socket.on("subscribe", (channel) => {
      socket.join(channel);
      console.log(`User subscribed to channel: ${channel}`);
    });

    socket.on("publish", (data) => {
      io.to(data.channel).emit("message", data.message);
    });
  }
});

app.listen(3000, () => {
  console.log("server listening on port 3000");
});

Socket.IO client version: 4.7.2

Publisher

const io = require("socket.io-client");
const socket = io("http://localhost:3000");

socket.on("connect", async () => {
  socket.emit("subscribe", "my-channel");

  let count = 0;
  setInterval(() => {
    socket.emit("publish", {
      channel: "my-channel",
      message: {
        count: count++,
      },
    });
    console.log("published: ", count);
  }, 1000);
});

Subscriber

const io = require("socket.io-client");
const socket = io("http://localhost:3000");

socket.on("connect", async () => {
  if (socket.recovered) {
    console.log("Reconnected to server", socket.rooms);
  } else {
    socket.emit("subscribe", 'my-channel');
  }
});

socket.on("message", (data) => {
  const { count } = data;
  console.log(count);
});

setInterval(() => {
  socket.io.engine?.close();
}, 10000);

Expected behavior
The expected behavior is after reconnection the subscriber should receive the buffered messages at reconnection period and continue receiving newer messages.

Platform:

  • Device: [i7-8750H CPU, 16 GB RAM]
  • OS: [Windows 10]

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions