首页 > 解决方案 > 将 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>

标签: expresssocket.iochild-process

解决方案


对于那些感兴趣的解决方案,可以使用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');
});


推荐阅读