In the socket.io acknowledgement example we see a client's send/emit being called back with the server's response. Is the same functionality available in the reverse direction - i.e. how does the server confirm client reception for a send/emit from the server? It would be nice to have a send/emit callback even just to indicate reception success. Didn't see this functionality documented anywhere... Thanks!
Asked
Active
Viewed 3,021 times
7
-
OK, tested it and it appears to be symmetrical.... (too bad docs are unclear on this). However, while testing I hit another issue: if client disconnects prior to sending a response, the emit/send callback on the sender never gets fired. Seems to me that the API may be improved if the callback mechanism be modified to include an error parameter, e.g.: socket.emit('ferret', 'tobi', function (**err**, data) {....... – Mark Mar 05 '12 at 17:30
-
I posted a direct question regarding my latest issue here: [link](http://stackoverflow.com/questions/9578134/reliable-messaging-under-socket-io), please disregard this previous Q, thanks. – Mark Mar 06 '12 at 05:03
3 Answers
3
Looking in the socket.io source I found that indeed ACKs are supported for server-sent messages (but not in broadcasts!) (lines 115-123 of socket.io/lib/socket.js):
if ('function' == typeof args[args.length - 1]) {
if (this._rooms || (this.flags && this.flags.broadcast)) {
throw new Error('Callbacks are not supported when broadcasting');
}
debug('emitting packet with ack id %d', this.nsp.ids);
this.acks[this.nsp.ids] = args.pop();
packet.id = this.nsp.ids++;
}
An example of how the ack should work (not tested):
// server-side:
io.on('msg', (data, ackCallback) => {
console.log('data from client', data);
ackCallback('roger roger');
});
// client-side:
socket.emit('msg', someData, (answer) => {
console.log('server\'s acknowledgement:', answer);
});

klh
- 605
- 7
- 23
-
Any chance you can post the syntax for how the client would send the acknowledgement when listening for an event? From the documentation (https://socket.io/docs/client-api/#socket-on-eventname-callback), it says that client-side socket.on() only accepts two arguments, the eventName and the callBack with the server sent data. – R J Nov 18 '17 at 18:38
1
Yes we can send a response back to the server from the Client(as acknowledgment )
According to new documentation of socket(4.x)
Server-side
let dataToSend={
test:"fromServer"
}
socket.timeout(5000).emit("my-event",dataToSend, (err, response) => {
if (err) {
// the other side did not acknowledge the event in the given delay
} else {
console.log(response);
}
});
Cleint- side
socket.on("my-event", (data, callback) => {
// any logic for data(that data come from server i.e { test:"fromServer" }
callback({ test: "test" });
});

Muhammad Saeed
- 41
- 1
- 3
0
If we want to be 100% sure the reception success, just add ack call is not enough because we also need to know whether the ack call is run or not.
The socket.io 3.0 document add this timeout example to show how to do that. But the timeout value is the tricky one.
const withTimeout = (onSuccess, onTimeout, timeout) => {
let called = false;
const timer = setTimeout(() => {
if (called) return;
called = true;
onTimeout();
}, timeout);
return (...args) => {
if (called) return;
called = true;
clearTimeout(timer);
onSuccess.apply(this, args);
}
}
socket.emit("hello", 1, 2, withTimeout(() => {
console.log("success!");
}, () => {
console.log("timeout!");
}, 1000));

Qiulang
- 10,295
- 11
- 80
- 129