express - 将 child_process 输出发送到 Socket.io
问题描述
我构建了一个简单的快速应用程序,用于child_process
运行命令。然后,我需要使用以下示例应用程序将每一行的输出发送到浏览器socket.io
,但它在命令完成后将所有输出行发送到单个字符串中。
有没有办法发送每一行并将其呈现在客户端/浏览器中?
//server.ts
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
const { exec } = require('child_process');
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('disconnect', () => {
console.log('user disconnected');
});
socket.on('chat message', (msg) => {
console.log('message: ' + msg);
// io.emit('chat message', msg);
});
socket.on('chat message2', (msg) => {
console.log('message: ' + msg);
exec("kind create cluster", (error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
io.emit('chat message', `error: ${error.message}` );
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
io.emit('chat message', `error: ${stderr}` );
return;
}
console.log(`stdout: ${stdout}`);
io.emit('chat message', new Buffer("> "+ `error: ${stdout}` ));
//ws.send(JSON.stringify({id:"shell",data:{stdout}}), function () {
//
// Ignore errors.
//
});
});
});
http.listen(3000, () => {
console.log('listening on *:3000');
});
这是客户端代码:
//index.html
<!doctype html>
<html>
<head>
<title>Socket.IO chat</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font: 13px Helvetica, Arial; }
form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
form input { border: 0; padding: 10px; width: 90%; margin-right: 0.5%; }
form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
#messages { list-style-type: none; margin: 0; padding: 0; }
#messages li { padding: 5px 10px; }
#messages li:nth-child(odd) { background: #eee; }
</style>
</head>
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
</body>
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script>
$(function () {
var socket = io();
$('form').submit(function(e){
e.preventDefault(); // prevents page reloading
socket.emit('chat message', $('#m').val());
socket.emit('chat message2', "Message 2 here!!");
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
});
</script>
<script>
var socket = io();
</script>
</html>
解决方案
对于那些感兴趣的解决方案,可以使用spawn
而不是exec
. 例如
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
//const { exec } = require('child_process');
const { spawn } = require('child_process');
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('disconnect', () => {
console.log('user disconnected');
});
socket.on('chat message', (msg) => {
console.log('message: ' + msg);
// io.emit('chat message', msg);
});
socket.on('chat message2', (msg) => {
console.log('message: ' + msg);
const sh = spawn('kind', ['create', 'cluster']);
sh.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
io.emit('chat message', `stdout: ${data}` );
});
sh.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
io.emit('chat message', `stderr: ${data}` );
});
sh.on('close', (code) => {
console.log(`child process exited with code ${code}`);
io.emit('chat message', `child process exited with code ${code}`);
});
});
});
http.listen(3000, () => {
console.log('listening on *:3000');
});
推荐阅读
- html - 如何在 MatTable 行上实现 OnClick 操作?
- google-apps-script - 从 Google 文档段落复制的图像插入了两次
- cdap - table-lookup 指令找不到准备数据的现有表
- azure-active-directory - Microsoft Graph API 获取联系信息
- java - Spring Integration Java DSL SFTP如何在处理程序中获取远程SFTP服务器信息
- javascript - 在(js)中加载新元素时如何重新定位HTML元素?
- c# - 如何将数据从模型 (MVC) 传递到 @url.Action() 以绘制图表
- javascript - 在 JS/PHP 中获取当前位置
- python - 使用多个进程和队列时优雅地处理键盘中断
- oracle - 提高视图交叉连接唯一值的性能(可扩展性)