同步 TCP 读入 Node.js

Synchronous TCP Read in Node.js

有没有办法在 node.js 中同步读取 TCP 套接字?

我很清楚如何通过向套接字的 'data' 事件添加回调来异步执行此操作:

socket.on('data', function(data) {
    // now we have the string data to do whatever with
});

我也知道尝试使用函数调用来阻止而不是注册回调违反节点的设计,但我们正在尝试更新一个旧节点模块,该模块充当我大学的客户端,同时保持向后兼容性。所以我们目前有:

var someData = ourModule.getData();

其中getData()之前背后有一堆逻辑,但现在我们只想发送到服务器"run getData()"并等待结果。这样所有逻辑都在服务器端,而不是重复的客户端和服务器端。该模块已经维护到服务器的 TCP 连接,因此我们只是搭载它。

以下是我尝试过的解决方案:

  1. 为隐藏在节点网络模块中类似于python的套接字库的套接字找到一个阻塞读取函数。

    string_from_tcp = socket.recv(1024)
    

    这里的问题是它似乎不存在(不足为奇,因为它违背了节点的意识形态)。

  2. 这个syncnet module添加了我需要的东西,但是没有Windows支持;所以我必须补充一点。

  3. 找到一个允许节点解除事件循环阻塞的函数,然后 return 返回,这样就可以了:

    var theData = null;
    clientSocket.on('data', function(data) {
        theData = data;
    });
    
    clientSocket.write("we want some data");
    
    while(theData === null) {
        someNodeFunctionThatUnblocksEventLoopThenReturnsHere(); // in this function node can check the tcp socket and call the above 'data' callback, thus changing the value of theData
    }
    
    // now theData should be something!
    

    这里很明显的问题是我认为这样的事情不存在。

  4. 使用 ECMAScript 6 生成器函数:

    var stringFromTcp = yield socketRead(1024);
    

    这里的问题是我们会强迫学生将他们的 JavaScript 客户端更新为这种新语法,并且理解 ES6 超出了使用它的课程的范围。

  5. 使用 node-gyp 并向我们的节点模块添加一个 C++ TCP 库的接口,该库支持同步读取,例如 boost 的 asio。这可能会奏效,但让节点模块与 boost 跨平台编译一直是一个巨大的痛苦。所以我来到 Stack Overflow 以确保我没有让这个问题过于复杂。

用最简单的话来说,我只是想创建一个支持同步 tcp 读取的命令行 JavaScript 程序。

还有其他想法吗?如果这在节点项目的上下文中看起来是亵渎神灵,请提前道歉,并感谢您的任何输入。

我最终选择了选项 5。我发现了一个用 C++ 构建的小型、快速且易于构建的 TCP 库 (netLink) and wrote a node module wrapper for it, aptly titled netlinkwrapper

该模块基于 Windows 和 Linux,但由于它是 C++ 插件,您需要配置 node-gyp 才能构建它。

我希望没有其他人必须像我使用这个模块那样搞砸 Node.js,但是如果你必须用 TCP 调用阻止事件循环,这可能是你唯一的选择。