我創建了一個自定義異步發射器來擁有一個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 客戶端確實接收到發射并正確回傳資料。
我做錯了什么,我該如何解決?
謝謝!
編輯,客戶端代碼是:
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
已記錄。我相信這是我的事件處理程式代碼的一些問題,但是我無法確定它。
uj5u.com熱心網友回復:
與 Socket.io 的回呼不同,一般稱為確認函式
為了實作回呼,發送者需要將函式添加到呼叫的最后一個引數socket.emit()。
例子:
發件人
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"
});
請注意回呼的第一個引數如何是“錯誤”
*在你的例子中:
*客戶端:*
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
}
}
);
服務器端:
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
};
根據這個結構編輯你的代碼并試一試。
uj5u.com熱心網友回復:
我最終重寫了我的代碼以不使用 Socket.IO 房間,并使用 aMap<string, Socket>并從那里獲取套接字,因此我可以使用 Socket.IO 回呼。
這可能不是最好的方法,但這是我能想到的唯一方法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/447839.html
標籤:javascript 节点.js 打字稿 插座 套接字.io
下一篇:seleniumwebdriver無法使用driver.find_element_by_css_selector點擊按鈕
