【问题标题】:Nodejs spawn remote tail and socket-io to clientNodejs向客户端生成远程tail和socket-io
【发布时间】:2017-09-14 12:58:53
【问题描述】:

我是 Nodejs 的新手,我正在构建一个应用程序,该应用程序将 ssh 发送到远程机器并获取日志文件的 tail -f

我通过socket-io(版本2.0.3)发送给客户端的日志文件行

现在我面临一个问题,即当第二个浏览器尝试tail 另一个日志时,新日志会发送到两个浏览器,而不仅仅是发出请求的浏览器。 我不确定这是我的socket-io 代码还是child_process 的问题。

这是服务器:

const express = require('express'),
    app = express(),
    path = require('path'),
    bodyParser = require('body-parser'),
    logger = require('morgan'),
    server = require('http').Server(app),
    io = require('socket.io')(server),
    spawn = require('child_process').spawn,
    events = require('events'),
    eventEmitter = new events.EventEmitter();


// Fix body of requests
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

// Log the requests
app.use(logger('dev'));

// Serve static files
app.use(express.static(path.join(__dirname, '.')));

// Add a basic route – index page
app.get('/', function (req, res) {
    res.sendFile(path.join(__dirname, 'index.html'));
});

io.on('connection', (socket) => {
    console.log(`client connected ${socket.client.id}`);
    eventEmitter.on('tail', (data) => {
        socket.tail = spawn('ssh', ['root@' + 'quality-p.company.com', 'tail -f', data.service], { shell: true });
        socket.tail.stdout.on('data', (data) => {
            console.log(`got new data ${data.toString()}`);
            socket.emit('newLine', {line: data.toString().replace(/\n/g, '<br />')});
        });
    });
});

app.get('/tail', (req, res) => {
    eventEmitter.emit('tail', req.query);
    res.sendStatus(200);
});

// Bind to a port
server.listen(3005, () => {
    console.log('running on localhost:' + 3005);
});

客户:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="./node_modules/socket.io-client/dist/socket.io.js"></script>
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script>
        $(() => {
            let socket = io();
            socket.on('connect', () => {
                console.log('connected');
            });
            socket.on('newLine', (data) => {
                console.log(`new data: ${data.line}`);
                $("#tailing").append(data.line);
            });
            $('#tail').click(() => {
                $.get('/tail', {
                    service: $('#service').val()
                });
            });
        });
    </script>
    <title>Title</title>
</head>
<body>
<select id="service">
    <option id="tnet" value="/var/log/tnet">tnet</option>
    <option id="consul" value="/var/log/consul">consul</option>
</select>
<button id="tail">tail</button>
<div id="tailing" style="background-color: antiquewhite;">
</div>
</body>
</html>

【问题讨论】:

  • 这是预期的行为。所有套接字都使用相同的eventEmitter,因此它们正在接收tail 事件。您应该将 GET 请求替换为 socket.io 发射,以便您可以将 tail 绑定到各个套接字。

标签: node.js socket.io child-process tail


【解决方案1】:

服务器

const express = require('express'),
    app = express(),
    path = require('path'),
    bodyParser = require('body-parser'),
    logger = require('morgan'),
    server = require('http').Server(app),
    io = require('socket.io')(server),
    spawn = require('child_process').spawn;


// Fix body of requests
app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(bodyParser.json());

// Log the requests
app.use(logger('dev'));

// Serve static files
app.use(express.static(path.join(__dirname, '.')));

// Add a basic route – index page
app.get('/', function(req, res) {
    res.sendFile(path.join(__dirname, 'index.html'));
});

var tails = {};

io.on('connection', (socket) => {
    console.log(`client connected ${socket.client.id}`);
    socket.on('tail', (data) => {
        socket.join(data.service);
        if (typeof tails[data.service] == "undefined") {
            tails[data.service] = spawn('ssh', ['root@' + 'quality-p.company.com', 'tail -f', data.service], {
                shell: true
            });
            tails[data.service].stdout.on('data', (data) => {
                console.log(`got new data ${data.toString()}`);
                io.to(data.service).emit('newLine', {
                    line: data.toString().replace(/\n/g, '<br />')
                });
            });
        }
    });
});


// Bind to a port
server.listen(3005, () => {
    console.log('running on localhost:' + 3005);
});

客户

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <script src="./node_modules/socket.io-client/dist/socket.io.js"></script>
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script>
        $(() => {
            let socket = io();
            socket.on('connect', () => {
                console.log('connected');
            });
            socket.on('newLine', (data) => {
                console.log(`new data: ${data.line}`);
                $("#tailing").append(data.line);
            });
            $('#tail').click(() => {
                socket.emit('tail', {
                    service: $('#service').val()
                });
            });
        });
    </script>
    <title>Title</title>
</head>

<body>
    <select id="service">
    <option id="tnet" value="/var/log/tnet">tnet</option>
    <option id="consul" value="/var/log/consul">consul</option>
</select>
    <button id="tail">tail</button>
    <div id="tailing" style="background-color: antiquewhite;">
    </div>
</body>

</html>

【讨论】:

  • 非常感谢。这真的很有帮助!
猜你喜欢
  • 1970-01-01
  • 2018-08-23
  • 1970-01-01
  • 2022-09-27
  • 2020-02-23
  • 2013-06-29
  • 1970-01-01
  • 2021-10-05
  • 1970-01-01
相关资源
最近更新 更多