node.js - Nodejs 向客户端生成远程 tail 和 socket-io

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

我对 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>

最佳答案

服务器

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>

关于node.js - Nodejs 向客户端生成远程 tail 和 socket-io,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46219867/

相关文章:

node.js - 事务如何在 sequelize Node js 中工作

c# - AES 在 .NET 中加密并使用 Node.js 加密解密?

node.js - 使用 Firebase CLI shell 测试可调用云函数

javascript - 在像 quizup 这样的多人游戏中,socket.io 房间在配对中是否有任何作用

javascript - socket.io 了解何时达到最大重新连接尝试限制

javascript - Nodejs 集群中从工作人员到工作人员的消息

node.js - 覆盖socket.io发射并开启?

mysql - 从 Electron.io 应用程序进行 MySql 备份的更好方法

javascript - 如何将 git-hooks 与 Electron 应用程序连接起来

c - 如何从 PROC 获取有关子进程的信息