问题描述
我生成了以下孩子: var spw = spawn('ping',['-n','10','127.0.0.1'])
和我希望在客户端(浏览器)一个而不是整体上接收ping结果。
I spawned the following child: var spw = spawn('ping', ['-n','10', '127.0.0.1'])
and I would like to receive the ping results on the client side (browser) one by one, not as a whole.
到目前为止,我已经尝试过:
So far I tried this:
app.get('/path', function(req, res) {
...
spw.stdout.on('data', function (data) {
var str = data.toString();
res.write(str + "\n");
});
...
}
那:
...
spw.stdout.pipe(res);
...
在两种情况下,浏览器都等待ping的10个完成,然后将结果打印为整个。我想一个接一个地做,如何实现?
In both cases browser waits 10 of the pings to complete, and then prints the result as a whole. I would like to have them one by one, how to accomplish that?
(客户只是在呼叫 ... /路径
和console.log结果)
(Client is just making a call to .../path
and console.logs the result)
编辑:虽然我确实相信websockets是实现此功能所必需的,我只想知道是否还有其他方法。我看到了几个令人困惑的,以及博客文章(在帖子,第一步OP将日志流式传输到浏览器)没有帮助,因此我决定赏金以引起注意。
Although I do believe that websockets are necessary to implement this, I just want to know whether there are any other ways. I saw several confusing SO answers, and blog posts (in this post, at step one OP streams the logs to the browser) which didn't help, therefore I decided to go for a bounty for some attention.
推荐答案
这是使用SSE(服务器发送的事件)的完整示例。
Here's a complete example using SSE (Server sent events). This works in Firefox and probably Chrome too:
var cp = require("child_process"),
express = require("express"),
app = express();
app.configure(function(){
app.use(express.static(__dirname));
});
app.get('/msg', function(req, res){
res.writeHead(200, { "Content-Type": "text/event-stream",
"Cache-control": "no-cache" });
var spw = cp.spawn('ping', ['-c', '100', '127.0.0.1']),
str = "";
spw.stdout.on('data', function (data) {
str += data.toString();
// just so we can see the server is doing something
console.log("data");
// Flush out line by line.
var lines = str.split("\n");
for(var i in lines) {
if(i == lines.length - 1) {
str = lines[i];
} else{
// Note: The double-newline is *required*
res.write('data: ' + lines[i] + "\n\n");
}
}
});
spw.on('close', function (code) {
res.end(str);
});
spw.stderr.on('data', function (data) {
res.end('stderr: ' + data);
});
});
app.listen(4000);
和客户端HTML:
<!DOCTYPE Html>
<html>
<body>
<ul id="eventlist"> </ul>
<script>
var eventList = document.getElementById("eventlist");
var evtSource = new EventSource("http://localhost:4000/msg");
var newElement = document.createElement("li");
newElement.innerHTML = "Messages:";
eventList.appendChild(newElement);
evtSource.onmessage = function(e) {
console.log("received event");
console.log(e);
var newElement = document.createElement("li");
newElement.innerHTML = "message: " + e.data;
eventList.appendChild(newElement);
};
evtSource.onerror = function(e) {
console.log("EventSource failed.");
};
console.log(evtSource);
</script>
</body>
</html>
运行 node index.js
并指向浏览器位于 http:// localhost:4000 / client.html
。
请注意,由于我正在运行OS X,因此必须使用 -c选项而不是 -n。
Run node index.js
and point your browser at http://localhost:4000/client.html
.Note that I had to use the "-c" option rather than "-n" since I'm running OS X.
这篇关于nodejs / express-将stdout立即流式传输到客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!