在服务器发送/发出时获得确认

时间:2012-03-05 14:39:24

标签: socket.io

在socket.io确认示例中,我们看到客户端的send / emit被服务器的响应回调。相反的功能是相同的 - 即服务器如何确认客户端接收来自服务器的发送/发送?发送/发出回调即使只是为了表明接收成功也会很好。没有看到任何地方记录此功能...... 谢谢!

2 个答案:

答案 0 :(得分:2)

查看socket.io source我发现服务器发送的消息确实支持ACK(但不支持广播!)( socket.io/lib/socket.js的第115-123行):

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++;
}

ack应如何工作(未经测试)的一个例子:

// 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);
});

答案 1 :(得分:0)

如果我们想100%确定接收成功,只添加ack调用是不够的,因为我们还需要知道ack调用是否运行。

The socket.io 3.0 document 添加这个超时示例来展示如何做到这一点。但超时值是一个棘手的问题。

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));