lvjian700
11/27/2010 - 4:26 PM

`tail -f` in Node.js and WebSockets

tail -f in Node.js and WebSockets

// ===================================
// `tail -f` in Node.js and WebSockets
// ===================================
//
// Usage:
// 
// git clone git://gist.github.com/718035.git tail.js
// cd tail.js
// git submodule update --init
//
// node server.js /path/to/your.log
//
// Connect with browser and watch changes in the logfile
//
//
require.paths.unshift('./lib/socket-io/lib/',
                      './lib/socket.io-node/lib/');

var http    = require('http'),
    io      = require('socket.io'),
    fs      = require('fs');

var spawn = require('child_process').spawn;

var filename = process.ARGV[2];
if (!filename) return util.puts("Usage: node <server.js> <filename>");

// -- Node.js Server ----------------------------------------------------------

server = http.createServer(function(req, res){
  res.writeHead(200, {'Content-Type': 'text/html'})
  fs.readFile(__dirname + '/index.html', function(err, data){
  	res.write(data, 'utf8');
  	res.end();
  });
})
server.listen(8000, '0.0.0.0');

// -- Setup Socket.IO ---------------------------------------------------------

var io = io.listen(server);

io.on('connection', function(client){
  console.log('Client connected');
  var tail = spawn("tail", ["-f", filename]);
  client.send( { filename : filename } );

  tail.stdout.on("data", function (data) {
    console.log(data.toString('utf-8'))
    client.send( { tail : data.toString('utf-8') } )
  }); 

});

console.log('Server running at http://0.0.0.0:8000/, connect with a browser to see tail output');
<!DOCTYPE html>
<html>
<head>
  <title>tail.js</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
  <script src="/socket.io/socket.io.js"></script>

  <style>
    body
      { color: #1a2c37;
        font-family: 'Helvetica', sans-serif; font-size: 86%;
        padding: 2em; }
    #info
      { font-size: 120%;
        font-weight: bold; }
    #tail
      { border: 1px solid #ccc;
        height: 300px;
        padding: 0.5em;
        overflow: hidden;
        position: relative;
        overflow-y: scroll; }
  </style>

</head>
<body>
  <pre id="info"></pre>
  <pre id="tail"></pre>

  <script>

  var Application = function() {
    
    var socket  = new io.Socket(null, {port: 8000});
    socket.connect();

    var lines = 0;

    socket.on('connect', function() {
      console.log('Connected to:', socket.host);
    });
    socket.on('message', function(message) {
      console.log('Received message:', message);
      if (message.filename) {
        $('#info').html( '$ tail -f ' + message.filename );
      };
      if (message.tail) {
        $('#tail').html( $('#tail').html() + message.tail );
        lines++
        $('#tail').scrollTop(lines*100)
      }
    });
    
    return {
      socket : socket
    };
  };
 
  $(function() { var app = Application(); });

  </script>

</body>
</html>
[submodule "lib/socket.io"]
	path = lib/socket.io
	url = http://github.com/LearnBoost/Socket.IO.git
[submodule "lib/socket.io-node"]
	path = lib/socket.io-node
	url = http://github.com/LearnBoost/Socket.IO-node.git