Skip to content

Issue with .to(room).emitWithAck() #5333

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
terryluan12 opened this issue Apr 22, 2025 · 2 comments
Open

Issue with .to(room).emitWithAck() #5333

terryluan12 opened this issue Apr 22, 2025 · 2 comments
Labels
question Further information is requested

Comments

@terryluan12
Copy link

Describe the bug
I came across a bug where if you broadcast an event to a room, it times out unless you explicitly set a timeout variable.

To Reproduce

Please fill the following code example:

Socket.IO server version: ^4.0.0

Server

import { createServer } from "node:http";
import { readFile } from "node:fs/promises";
import { Server } from "socket.io";

const port = process.env.PORT || 3000;

const httpServer = createServer(async (req, res) => {
  if (req.url !== "/") {
    res.writeHead(404);
    res.end("Not found");
    return;
  }
  // reload the file every time
  const content = await readFile("index.html");

  res.writeHead(200, {
    "Content-Type": "text/html",
    "Content-Length": Buffer.byteLength(content),
  });
  res.end(content);
});

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

const roomCode = "Test room code"

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

  socket.on("joinRoom", async (username, ack) => {
    console.log(`${username} joining`);
    socket.join(roomCode);

    // This doesn't work
    const response = await socket.to(roomCode).emitWithAck("userJoined", username);

    // This does
    // const response = await socket.to(roomCode).timeout(5000).emitWithAck("userJoined", username);

    ack(response);
  })

});

httpServer.listen(port, () => {
  console.log(`server listening at http://localhost:${port}`);
});

Socket.IO client version: ^4.0.0

Client

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

const port = process.env.PORT || 3000;

const socket = io(`http://localhost:${port}`);
const socket2 = io(`http://localhost:${port}`);


socket.on("userJoined", (username, ack) => {
  ack("username1")
})

const response1 = await socket.emitWithAck("joinRoom", "username1");
console.log(`Response 1 is ${response1}`);

const response2 = await socket2.emitWithAck("joinRoom", "username2")
console.log(`Response 2 is ${response2}`);

Expected behavior
It should work with or without the explicit timeout set.

Platform:

  • OS: Ubuntu 22.04.5 LTS
@terryluan12 terryluan12 added the to triage Waiting to be triaged by a member of the team label Apr 22, 2025
@terryluan12
Copy link
Author

terryluan12 commented Apr 22, 2025

In addition, can I get some clarification whether a emitWithAck chained to a to(room) is supported. Officially, it seems not to be per this, but I've seen multiple places where people are using it, such as here, or even in the code(if I'm reading it correctly). Am I misunderstanding the documentation, or are the documents outdated?

darrachequesne added a commit to socketio/socket.io-website that referenced this issue Apr 24, 2025
@darrachequesne
Copy link
Member

@terryluan12 the timeout value is indeed mandatory, in order to prevent memory leaks (for example, if some clients fail to reply).

We could maybe add a default timeout in the options though (mirroring the ackTimeout on the client-side).

Officially, it seems not to be per this,

Oops, I've updated the documentation, because acknowledgements are now supported when broadcasting (since [email protected], released in 2022). Good catch!

@darrachequesne darrachequesne added question Further information is requested and removed to triage Waiting to be triaged by a member of the team labels Apr 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants