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

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

Open ABE-Mark45 opened this issue 2 years ago • 0 comments

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]

ABE-Mark45 avatar Aug 26 '23 01:08 ABE-Mark45