2017-09-14 6 views
1

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> 
+0

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. –

Répondre

1

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; 


// 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', ['[email protected]' + '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); 
}); 

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(() => { 
       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> 
+0

Merci beaucoup. Cela a vraiment vraiment aidé! – Moshe