简体   繁体   English

Socket.IO - socket.on 未运行

[英]Socket.IO - socket.on not being ran

I have created a custom async emitter to have a server -> client -> server method.我已经创建了一个自定义异步发射器来使用server -> client -> server方法。

However, it doesn't work as expected.但是,它没有按预期工作。 It emits the event, but does not run the callback.它发出事件,但不运行回调。

With Socket.IO debugging enabled, I can see that the socket.io:socket is logging that it is emitting the correct event.启用 Socket.IO 调试后,我可以看到socket.io:socket正在记录它正在发出正确的事件。

Function code: Function 代码:

export async function asyncEmit<T>(
  region: string,
  socket: Server,
  event: string,
  data: {
    id: any;
    [k: string]: any;
  }
): Promise<{ result: T; error: boolean }> {
  return new Promise((resolve, reject) => {
    socket.to(region).emit(event, data);

    const cb = (res: { result: T; error: boolean }, ack: any) => {
      ack();
      if (res.error) {
        reject(res.result);
      }
      socket.off(`${data.id}-${event}`, cb);
      resolve(res);
    };

    socket.on(`${data.id}-${event}`, cb);
    setTimeout(() => {
      socket.off(event, cb);
      reject('Timed out.');
    }, 5000);
  });
}

Some example code I'm using to run the function:我用来运行 function 的一些示例代码:

    const res = await asyncEmit<{ statistics: { members: number } }>(
      botRegion,
      socket,
      'statistics',
      { id: botId }
    );

The Socket.IO client does receive the emit and does return data correctly. Socket.IO 客户端确实接收到发射并正确返回数据。

What am I doing wrong, and how can I fix it?我做错了什么,我该如何解决?

Thanks!谢谢!

Edit, client side code is:编辑,客户端代码是:

        this.socketio.timeout(5000).emit(
          `${uuid}-statistics`,
          {
            result: { statistics: { members: guild.memberCount } },
            error: false,
          },
          (data: any, err: any) => {
            if (err) {
              this.logger.error(err);
            }
            if (data) {
              return;
            }
          }
        );

It does time out and log socket.io-client:socket event with ack id 0 has timed out after 5000 ms +5s它确实超时并记录socket.io-client:socket event with ack id 0 has timed out after 5000 ms +5s

However on the server-side:但是在服务器端:

  socket.io:socket got packet {"type":2,"nsp":"/","id":0,"data":["......-statistics",{"result":{"statistics":{"members":35}},"error":false}]} +3s
  socket.io:socket emitting event ["......-statistics",{"result":{"statistics":{"members":35}},"error":false}] +0ms
  socket.io:socket attaching ack callback to event +0ms
  socket.io:socket dispatching an event ["......-statistics",{"result":{"statistics":{"members":35}},"error":false},null] +0ms

is logged.被记录。 I believe this is some issue with my event handler code, however I can't pinpoint it.我相信这是我的事件处理程序代码的一些问题,但我无法查明它。

Callbacks with Socket.io are different and are generally referred to as acknowledgement functions与Socket.io的回调不同,一般称为确认函数

In order to implement callbacks, the sender would need to add the function to the last parameter of the socket.emit() call.为了实现回调,发送方需要将 function 添加到socket.emit()调用的最后一个参数。

Example:例子:

Sender发件人

socket.emit("statistics", {test: "just a message"}, (response) => {
  console.log(response); // <-- should output "success"
});

Receiver接收者

socket.on("statistics", (data, callback) => {
  console.log(data.test); // <-- should output "just a message"
  callback("success");//<-- this will return to the sender/emitter
});

With timeout:超时:

socket.timeout(5000).emit("statistics", {test: "just a message"}, (err, response) => {
  if (err)
    // the event was not acknowledged by the receiver in the delay given
  else
    console.log(response); // <-- output is "success"
});

Do note how the first argument of the callback is the " error "请注意回调的第一个参数是“错误


*In you example: *在你的例子中:

*Client-side:* *客户端:*
 this.socketio.timeout(5000).emit( `${uuid}-statistics`, { result: { statistics: { members: guild.memberCount } }, error: false, }, (err: any, data: any) => { if (err) { this.logger.error(err); } if (data) { console.log(data);//<-- this is where your callback resolves to } } );

Server-side:服务器端:

 const cb = (res: { result: T; error: boolean }, ack: any) => { //do whatever you want with res if (res.error) { console.log("Error:",res.result); ack("Errorfrom server"); } socket.off(`${data.id}-${event}`, cb); console.log("Success:",res.result) ack("Success from server");//<--this callback will send back to the emitter };

Edit your code according to this structure and give it a try.根据此结构编辑您的代码并试一试。

I ended up rewriting my code to not use Socket.IO rooms, and to use a Map<string, Socket> and get the socket from there, so I can use Socket.IO callbacks.我最终重写了我的代码以不使用 Socket.IO 房间,并使用Map<string, Socket>并从那里获取套接字,因此我可以使用 Socket.IO 回调。

This may not be the best way, but it's the only way I could think of.这可能不是最好的方法,但这是我能想到的唯一方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM