首页 > 解决方案 > 执行另一个函数时 Websocket 事件侦听器被锁定

问题描述

我在最新版本的 NodeJS 中编写了一个 API。它的目标是拥有一个用户可以发送代码的 RESTful 接口和一个代码可以使用的 Websocket 接口

唯一的问题是我无法client.on('data'与我的 RESTful 方法同时运行事件侦听器。

所以如果我这样做

global.writeRequest("#get_pos 1") // will request data from my Websocket Server and respond within 10ms~
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 4000); // wait 4 second to make sure the latency of the request doesn't affect the result
console.log("this is a test");

请求最后显示,即使它应该首先显示。

此命令的结果:

this is a test // our console.log
POST /api/data 200 2.373ms -12 // end of the RESTful Method
Server says: %pos[1]:488 // result of our global.writeRequest from earlier except it's shown at the end

更奇怪的是,事件侦听器似乎在整个 RESTful 方法期间被锁​​定,考虑到我想发送和使用来自事件侦听器的数据,这是一个问题。

更奇怪的是,当我在这样global.writeRequest的一种方法中执行多个操作时:

global.writeRequest("#get_pos 1")
global.writeRequest("#get_pos 2")
global.writeRequest("#get_pos 3") // will request data from my Websocket Server and respond within 10ms~
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 4000); // wait 4 second to make sure the latency of the request doesn't affect the result
console.log("this is a test");

我最终得到以下结果

this is a test // our console.log
POST /api/data 200 2.373ms -12 // end of the RESTful Method
Server says: %pos[1]:488%pos[2]:488%pos[3]:488 

但它应该在之前显示以下内容console.log

Server says: %pos[1]:488
Server says: %pos[2]:488
Server says: %pos[3]:488 

所以我推测当我执行另一个函数时事件监听器被锁定所以我试图把所有的函数都放进去,async但我遇到了同样的问题。

编码:

client_websocket.js

const net = require('net');
const client = new net.Socket();
const port = 50000;
const host = '127.0.0.1';
const password = "something";

client.connect(port, host, async function () {
    console.log('Connected');
    client.write(password);
});

client.on('close', async function () {
    console.log('Connection closed');
});

writeRequest = async function (commmand) {
    client.write(commmand);
    return "Command sent!"
};
client.on('data', async function (data) {
    console.log("Server says: " + data);
}

requests_api.js

var Task = {
    sendData: async function (id) {
        console.log("code: " + id.code);
        return evalCode(id.code);
    }
};

async function evalCode(code) {
    global.getAllStats();
    return eval(code);
}

然后我eval(code);可以使用 websocket 接口

在执行我的 RESTful 方法时解锁我的事件侦听器有什么想法吗?

标签: javascriptnode.jsrestapiwebsocket

解决方案


似乎Atomics.wait()阻塞了主 JS 线程,因此在该线程上没有其他事件(包括任何套接字事件)可以被处理,直到它完成。

您需要了解 Javascript 的事件模型,并且真的不应该Atomics.wait()在主服务器线程上使用它,因为它会阻止所有其他事件的处理。

尚不完全清楚您要尝试解决什么问题Atomics.wait(),但如果您只想在一段时间后运行一些代码,请使用 asetTimeout()并将代码放入该回调中。这将允许在等待计时器触发时处理事件。这是 Javascript 事件模型的一个重要方面。


推荐阅读