Socket.IO - socket.on 不是 运行
Socket.IO - socket.on not being ran
我已经创建了一个自定义异步发射器以具有 server -> client -> server
方法。
但是,它没有按预期工作。它发出事件,但不 运行 回调。
启用 Socket.IO 调试后,我可以看到 socket.io:socket
正在记录它正在发出正确的事件。
函数代码:
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);
});
}
我用来 运行 函数的一些示例代码:
const res = await asyncEmit<{ statistics: { members: number } }>(
botRegion,
socket,
'statistics',
{ id: botId }
);
Socket.IO 客户端确实收到了发射并且 return 数据正确。
我做错了什么,我该如何解决?
谢谢!
编辑,客户端代码为:
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;
}
}
);
确实超时并记录 socket.io-client:socket event with ack id 0 has timed out after 5000 ms +5s
然而在服务器端:
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
已记录。我相信这是我的事件处理程序代码的一些问题,但我无法查明它。
与Socket.io的回调不同,一般称为确认函数
为了实现回调,发送方需要将函数添加到 socket.emit()
调用的 last 参数。
示例:
发件人
socket.emit("statistics", {test: "just a message"}, (response) => {
console.log(response); // <-- should output "success"
});
接收器
socket.on("statistics", (data, callback) => {
console.log(data.test); // <-- should output "just a message"
callback("success");//<-- this will return to the sender/emitter
});
有超时:
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"
});
请注意注意回调的第一个参数是“error”
*在你的例子中:
*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
};
根据此结构编辑您的代码并试一试。
我最终重写了我的代码以不使用 Socket.IO 个房间,并使用 Map<string, Socket>
并从那里获取套接字,因此我可以使用 Socket.IO 回调。
这可能不是最好的方法,但这是我能想到的唯一方法。
我已经创建了一个自定义异步发射器以具有 server -> client -> server
方法。
但是,它没有按预期工作。它发出事件,但不 运行 回调。
启用 Socket.IO 调试后,我可以看到 socket.io:socket
正在记录它正在发出正确的事件。
函数代码:
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);
});
}
我用来 运行 函数的一些示例代码:
const res = await asyncEmit<{ statistics: { members: number } }>(
botRegion,
socket,
'statistics',
{ id: botId }
);
Socket.IO 客户端确实收到了发射并且 return 数据正确。
我做错了什么,我该如何解决?
谢谢!
编辑,客户端代码为:
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;
}
}
);
确实超时并记录 socket.io-client:socket event with ack id 0 has timed out after 5000 ms +5s
然而在服务器端:
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
已记录。我相信这是我的事件处理程序代码的一些问题,但我无法查明它。
与Socket.io的回调不同,一般称为确认函数
为了实现回调,发送方需要将函数添加到 socket.emit()
调用的 last 参数。
示例:
发件人
socket.emit("statistics", {test: "just a message"}, (response) => {
console.log(response); // <-- should output "success"
});
接收器
socket.on("statistics", (data, callback) => {
console.log(data.test); // <-- should output "just a message"
callback("success");//<-- this will return to the sender/emitter
});
有超时:
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"
});
请注意注意回调的第一个参数是“error”
*在你的例子中:
*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
};
根据此结构编辑您的代码并试一试。
我最终重写了我的代码以不使用 Socket.IO 个房间,并使用 Map<string, Socket>
并从那里获取套接字,因此我可以使用 Socket.IO 回调。
这可能不是最好的方法,但这是我能想到的唯一方法。