Je suis assez nouveau à Nodejs et je construis une application qui ssh
à une machine distante et obtenir un tail -f
d'un fichier journal.Nodejs spawn distant tail et socket-io au client
Les lignes du fichier journal que je reçois j'envoie au client via socket-io
(v. 2.0.3)
Maintenant, je suis face à un problème que lorsqu'un second navigateur tente de tail
une différent, le nouveau journal est envoyé aux deux navigateurs au lieu de seulement celui qui a fait la demande. Je ne sais pas si c'est un problème avec mon code socket-io
ou le child_process
.
Voici le serveur:
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', ['[email protected]' + '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);
});
Client:
<!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>
Ce qui est attendu être haviour. Toutes les sockets utilisent le même 'eventEmitter' pour recevoir l'événement' tail'. Vous devez remplacer la requête 'GET' par un socket.io afin de pouvoir lier' tail' aux sockets individuels. –