【发布时间】:2016-09-19 12:37:40
【问题描述】:
我正在阅读一本教你 Node.JS 基础知识的书,并且我创建了几个程序 - 一个响应者和一个请求者。
响应者:
"use strict";
const fs = require("fs");
const zmq = require("zmq");
const responder = zmq.socket("rep"); // Create socket to reply to client requests
// Handle incoming requests
responder.on("message", function(data) {
// Parse incoming message
let request = JSON.parse(data);
console.log("Received request to get: " + request.path);
// Read file and reply with content
fs.readFile(request.path, function(err, content) {
console.log("Sending response content");
responder.send(JSON.stringify({
content: content.toString(),
timestamp: Date.now(),
pid: process.pid
}));
});
});
// Listen on TCP port 5433
responder.bind("tcp://127.0.0.1:5433", function(err) {
console.log("Listening for zmq requesters...");
});
// Close the responder when the Node process ends
process.on("SIGINT", function() {
console.log("Shutting down...");
responder.close();
});
请求者:
"use strict";
const zmq = require("zmq");
const filename = process.argv[2];
const requester = zmq.socket("req"); // Create request endpoint
// Handle replies from responder
requester.on("message", function(data) {
let response = JSON.parse(data);
console.log("Received response:", response);
});
requester.connect("tcp://localhost:5433");
// Send request for content
for (let i=1; i <= 3; i++) {
console.log("Sending request " + i + " for " + filename);
requester.send(JSON.stringify({
path: filename
}));
}
所以我运行启动良好的响应程序,然后像这样运行请求程序(target.txt 已经存在于文件系统中):
> node requester.js target.txt
奇怪的是,鉴于 Node.js 的单线程,我希望输出总是是:
Sending request 1 for target.txt
Sending request 2 for target.txt
Sending request 3 for target.txt
Received response: { ...
但是,有时我会这样,但有时我会:
Sending request 1 for target.txt
Sending request 2 for target.txt
Received response: { ...
Sending request 3 for target.txt
这怎么可能?事件循环正在执行我的for 循环,这应该意味着“发送请求”行得到输出,然后它有机会调用响应处理程序。为什么有时会在记录第三个请求之前记录响应?
【问题讨论】:
-
我认为鉴于网络的不确定性,您不应依赖请求/响应的顺序。您现在可以发出 request1,然后发出 request2 和 request3,但您可以按任何顺序获得响应。
-
@klikas 你了解 Node.js 的单线程本质吗?
-
我知道 Node.js 是单线程的,我只是不知道你如何才能真正确保在现实世界中,你的请求会以特定的顺序到达你的服务器一直都是。
-
我猜这与包含本机代码的
zmq有关,并且在这种情况下语义不同。该行为表明,如果响应可用,则在send实现中调用提供给on的回调。 -
@cartant 这是唯一的可能性。回调必须在发送操作期间同步调用才能发生。
标签: javascript node.js zeromq