Description
Environment
@socket.io/postgres-adapter
: 0.4.0socket.io
: 4.8.xpg
: 8.16.x- Node.js: 22
- PostgreSQL: 14.x
Problem description
When using serverSideEmit(..., callback)
, the callback is invoked with:
(err, responses) => {
console.log(err); // null
console.log(responses); // [] ← empty
}
The event is never delivered to any other server, and the handler (io.on(...)
) is never triggered on them.
However, if each individual server sends at least one serverSideEmit()
(even a dummy one), things start working — the events are delivered and acknowledged as expected.
Note: If
serverSideEmit()
is used without a callback, the event is delivered to other servers even before they have sent any emits themselves. The issue only affects the ACK-based communication (serverSideEmit(..., callback)
).
Root cause
The Postgres adapter does not deliver serverSideEmit(..., callback) events to other servers unless those servers have already started sending their own heartbeats.
Until a server sends a serverSideEmit()
:
- It is connected and listening on the correct
LISTEN
channel - It can receive broadcast events without callback
- But it will not be discoverable by other servers for ACK-based communication (
serverSideEmit(..., callback)
)
As a result:
- The initiating server sends a request and waits for ACKs
- But other servers ignore the request because they don't recognize the source as active
- The callback returns with
responses = []
Minimal reproduction
// on all servers:
io.on("test-ack", (data, callback) => {
console.log("received:", data);
callback("ack from " + process.pid);
});
// on emitter server:
setTimeout(() => {
io.serverSideEmit("test-ack", "hello", (err, responses) => {
console.log("err:", err); // null
console.log("responses:", responses); // [] if heartbeat not yet started on other servers
});
}, 1000);
Workaround
Ensure that every server sends a dummy serverSideEmit()
after startup to trigger the heartbeat:
io.serverSideEmit("__init__", "poke");
This ensures each server becomes discoverable by others and can participate in ACK-based messaging.