use*_*766 1 javascript browser shell node.js
我有一个节点js服务器,它触发我有的shell脚本.代码如下(简单的Hello World示例):
var http = require("http");
function onRequest(request, response) {
console.log("Request received.");
response.writeHead(200, {"Content-Type": "text/plain"});
var spawn = require('child_process').spawn;
//executes my shell script - main.sh when a request is posted to the server
var deploySh = spawn('sh', [ 'main.sh' ]);
//This lines enables the script to output to the terminal
deploySh.stdout.pipe(process.stdout);
//Simple response to user whenever localhost:8888 is accessed
response.write("Hello World");
response.end();
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
Run Code Online (Sandbox Code Playgroud)
代码工作正常 - 服务器启动,无论何时在浏览器中加载(请求)页面,shell脚本都在服务器上运行并在终端上输出结果.
现在,我想将结果显示回客户端浏览器而不是"Hello World".怎么做?请注意,脚本需要4-5秒才能执行并生成结果.
您有两种选择:
转换您的函数以使用child_process.exec方法而不是child_process.spawn方法.这将缓冲发送到stdout内存中的所有数据,并允许您作为一个块发送到浏览器:
var http = require("http"),
exec = require("child_process").exec;
function onRequest(request, response) {
console.log("Request received.");
response.writeHead(200, {"Content-Type": "text/plain"});
//executes my shell script - main.sh when a request is posted to the server
exec('sh main.sh', function (err, stdout, stderr) {
if (err) handleError();
//Print stdout/stderr to console
console.log(stdout);
console.log(stderr);
//Simple response to user whenever localhost:8888 is accessed
response.write(stdout);
response.end();
});
}
http.createServer(onRequest).listen(8888, function () {
console.log("Server has started.");
});
Run Code Online (Sandbox Code Playgroud)
如果要保留该child_process.spawn方法,则需要在堆栈中引入实时网络,以便在从子进程接收事件时将数据事件推送到浏览器.看一下socket.io或(推荐)SockJS,以便在服务器和客户端之间建立实时通信.
我想指出上面代码中的一个缺陷,从长远来看,这将最终伤害到你对节点的未来努力.
function onRequest(request, response) {
console.log("Request received.");
response.writeHead(200, {"Content-Type": "text/plain"});
var spawn = require('child_process').spawn;
Run Code Online (Sandbox Code Playgroud)
在上面的最后一行中,您需要child_process在每个请求上使用该模块.这不仅会给每个请求增加不必要的开销,如果不小心,最终会遇到模块缓存问题.建议所有要求的调用都发生在模块范围的顶部而不是其他地方.在构建真正的同步CLI工具时,唯一一次"接受"需要在逻辑中间进行调用的是 - 但即便如此,最好将所有需求组织在模块范围的顶部以便于阅读.