我正在使用 tcp 服務器來接收和處理 Node.js 中的資料包。它應該收到 2 個資料包:
- “create”用于在資料庫中創建物件。它首先檢查物件是否已經存在,然后創建它。(-> 需要一些時間的程序)
- "update" 用于更新資料庫中新創建的物件
為簡單起見,我們假設第一步總是比第二步花費的時間更長。(在我的原始代碼中總是如此)
這是一個 MWE:
const net = require("net");
const server = net.createServer((conn) => {
conn.on('data', async (data) => {
console.log(`Instruction ${data} recieved`);
await sleep(1000);
console.log(`Instruction ${data} done`);
});
});
server.listen(1234);
const client = net.createConnection(1234, 'localhost', async () => {
client.write("create");
await sleep(10); // just a cheap workaround to "force" sending 2 packets instead of one
client.write("update");
});
// Just to make it easier to read
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
如果我運行此代碼,我會得到:
Instruction create recieved
Instruction update recieved
Instruction create done
Instruction update done
但我希望“創建”指令阻止conn.on('data', func)直到最后一個回呼異步回傳。當前代碼嘗試在資料庫中創建條目之前更新條目,這并不理想。
有沒有(優雅的)方法來實作這一目標?我懷疑某種存盤資料的緩沖區和某種處理資料的作業回圈?但是我如何避免運行一個阻塞事件回圈的無限回圈?(事件回圈是正確的術語,是嗎?)
注意:我有更多的邏輯來處理碎片等。但這解釋了我遇到的問題。
uj5u.com熱心網友回復:
我設法讓它與包async-fifo-queue 一起使用。這不是最干凈的解決方案,但它應該做我想要的并且盡可能高效(使用 async/await 而不是無限回圈)。
代碼:
const net = require("net");
const afq = require("async-fifo-queue");
const q = new afq.Queue();
const server = net.createServer((conn) => {
conn.on('data', q.put.bind(q));
});
server.listen(1234);
const client = net.createConnection(1234, 'localhost', async () => {
client.write("create");
await sleep(10);
client.write("update");
});
(async () => {
while(server.listening) {
const data = await q.get();
console.log(`Instruction ${data} recieved`);
await sleep(1000);
console.log(`Instruction ${data} done`);
}
})();
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
uj5u.com熱心網友回復:
當您收到“創建”事件時,您可以暫停套接字。完成后,您可以恢復套接字。例子:
const server = net.createServer((conn) => {
conn.on('data', async (data) => {
if (data === 'create') {
conn.pause()
}
console.log(`Instruction ${data} recieved`);
await sleep(1000);
console.log(`Instruction ${data} done`);
if (data === 'create') {
conn.resume()
}
});
});
server.listen(1234);
const client = net.createConnection(1234, 'localhost', async () => {
client.write("create");
await sleep(10); // just a cheap workaround to "force" sending 2 packets instead of one
client.write("update");
});
// Just to make it easier to read
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/313383.html
上一篇:Ejabberd網路層性能不佳
