同步 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 连接,因此我们只是搭载它。
以下是我尝试过的解决方案:
为隐藏在节点网络模块中类似于python的套接字库的套接字找到一个阻塞读取函数。
string_from_tcp = socket.recv(1024)
这里的问题是它似乎不存在(不足为奇,因为它违背了节点的意识形态)。
这个syncnet module添加了我需要的东西,但是没有Windows支持;所以我必须补充一点。
找到一个允许节点解除事件循环阻塞的函数,然后 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!
这里很明显的问题是我认为这样的事情不存在。
使用 ECMAScript 6 生成器函数:
var stringFromTcp = yield socketRead(1024);
这里的问题是我们会强迫学生将他们的 JavaScript 客户端更新为这种新语法,并且理解 ES6 超出了使用它的课程的范围。
使用 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 调用阻止事件循环,这可能是你唯一的选择。
有没有办法在 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 连接,因此我们只是搭载它。
以下是我尝试过的解决方案:
为隐藏在节点网络模块中类似于python的套接字库的套接字找到一个阻塞读取函数。
string_from_tcp = socket.recv(1024)
这里的问题是它似乎不存在(不足为奇,因为它违背了节点的意识形态)。
这个syncnet module添加了我需要的东西,但是没有Windows支持;所以我必须补充一点。
找到一个允许节点解除事件循环阻塞的函数,然后 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!
这里很明显的问题是我认为这样的事情不存在。
使用 ECMAScript 6 生成器函数:
var stringFromTcp = yield socketRead(1024);
这里的问题是我们会强迫学生将他们的 JavaScript 客户端更新为这种新语法,并且理解 ES6 超出了使用它的课程的范围。
使用 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 调用阻止事件循环,这可能是你唯一的选择。