public
Last active — forked from karmi/.gitignore

  • Download Gist
00-INSTALL
1 2 3 4
IMPORTANT: this is outdated, go to https://github.com/netroy/Lockets
 
 
"npm install socket-io" & you are ready to go
index.html
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
<!DOCTYPE html>
<html>
<head>
<title>Websockets tail Server</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 type="text/css" rel="stylesheet">
body{background-color:#222;}
#info{ font-size: 32px; color:#000;text-shadow:#444 1px 1px 2px; text-align:right;margin:20px 10px;text-transform:lowercase;}
#tail{ border: 1px solid #444; overflow-x:hidden; overflow-y:auto; background-color:#333; color: #EEE; text-shadow:#000 0 0 2px; height: 400px; padding: 10px; font-size:12px; line-height:20px;}
.trebuchet{font-family: "Trebuchet MS","Lucida Sans Unicode","Lucida Grande","Lucida Sans",Arial,sans-serif;}
.monospace{font-family: Monaco,"Bitstream Vera Sans Mono","Lucida Console",Terminal,monospace;}
.selection::selection , .selection *::selection{background: #EEE;color:#000;border-color:#000; text-shadow:#fff 0 0 2px;}
.selection::-moz-selection , .selection *::-moz-selection{background: #EEE;color:#000;border-color:#000; text-shadow:#fff 0 0 2px;}
</style>
</head>
<body>
<div id="info" class="trebuchet"></div>
<div id="tail" class="monospace selection"></div>
<script type="text/javascript">
(function() {
var lines = 0, notice = $("#info"), buffer = $('#tail');
var socket = new io.Socket(null, {port: 8000});
socket.connect();
socket.on('connect', function() {
console.log('Connected to:', socket.host);
});
socket.on('message', function(message) {
if (message.filename) {
notice.html( 'watching ' + message.filename );
}else if (message.tail) {
buffer.append( message.tail.join('<br/>') );
buffer.scrollTop(lines*100)
lines = lines + message.tail.length;
}else if(message.clear) {
$('$tail').empty();
}else console.log('Received message:', message);
});
})();
</script>
</body>
</html>
server.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
// ===================================
// `tail -f` in Node.js and WebSockets
// ===================================
var http = require('http'),
io = require('socket.io'),
fs = require('fs');
 
var backlog_size = 2000;
var filename = process.ARGV[2];
if (!filename) return util.puts("Usage: node <server.js> <filename>");
 
// -- Node.js HTTP 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 socket = io.listen(server);
socket.on('connection', function(client){
client.send( { filename : filename } );
fs.stat(filename,function(err,stats){
if (err) throw err;
var start = (stats.size > backlog_size)?(stats.size - backlog_size):0;
var stream = fs.createReadStream(filename,{start:start, end:stats.size});
stream.addListener("data", function(lines){
lines = lines.toString('utf-8');
lines = lines.slice(lines.indexOf("\n")+1).split("\n");
client.send({ tail : lines});
});
});
});
 
// watch the file now
fs.watchFile(filename, function(curr, prev) {
if(prev.size > curr.size) return {clear:true};
var stream = fs.createReadStream(filename, { start: prev.size, end: curr.size});
stream.addListener("data", function(lines) {
socket.broadcast({ tail : lines.toString('utf-8').split("\n") });
});
});
 
console.log('Server running at http://0.0.0.0:8000/, connect with a browser to see tail output');

In 00-INSTALL it says:

"npm install socket-io" & you are ready to go

However, I found (using node 0.8.7) I had to use a . instead of a -, i.e.

"npm install socket.io" & you are ready to go

With node v0.8.7 ARGV needs to be in lowercase, argv but I also get the following error:

/home/tom/node-0.8.7/tomcode/gist867575-1a493853a42c890348491fbfc92c4c245a68331d/server.js:43
    socket.broadcast({ tail : lines.toString('utf-8').split("\n") });
           ^
TypeError: Object #<Manager> has no method 'broadcast'
    at null.<anonymous> (/home/tom/node-0.8.7/tomcode/gist867575-1a493853a42c890348491fbfc92c4c245a68331d/server.js:43:12)
    at EventEmitter.emit (events.js:88:17)
    at ReadStream._emitData (fs.js:1362:10)
    at afterRead (fs.js:1344:10)
    at Object.wrapper [as oncomplete] (fs.js:362:17)

the structure of calls has changed some time ago, so broadcast is not available anymore. below is modified version that works for me. Please note that client-side javascript has to be changed as well:

// ===================================
// `tail -f` in Node.js and WebSockets
// ===================================
var http    = require('http'),
    io      = require('socket.io'),
    fs      = require('fs'),
    util    = require('util');

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

// -- Node.js HTTP 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 socket = io.listen(server);
socket.on('connection', function(client){
  client.emit('start', { filename: filename })
  fs.stat(filename,function(err,stats){
    if (err) throw err;
    var start = (stats.size > backlog_size)?(stats.size - backlog_size):0;
    var stream = fs.createReadStream(filename,{start:start, end:stats.size});
    // initially stream the file
    stream.addListener("data", function(lines){
      lines = lines.toString('utf-8');
      lines = lines.slice(lines.indexOf("\n")+1).split("\n");
      client.emit('tail', { lines: lines })
    });
  });


  // watch the file and emit new event once new data arrives
  fs.watchFile(filename, function(curr, prev) {
    console.log("file changed");
    if(prev.size > curr.size) return {clear:true};
    var stream = fs.createReadStream(filename, { start: prev.size, end: curr.size});
    stream.on("data", function(lines) {
      client.emit('tail', { lines : lines.toString('utf-8').split("\n") });
    });
  });

});


console.log('Server running at http://0.0.0.0:8000/, connect with a browser to see tail output');

changed exerpts

 <script type="text/javascript">
  (function() {
    var lines = 0, notice = $("#info"), buffer = $('#tail');
    var socket = io.connect('http://127.0.0.1:8000/');
    socket.on('connect', function() {
      console.log('Connected to stream');
    });


    socket.on('tail', function(msg) {
      console.log("Message:");
      console.dir(msg);
      buffer.append(msg.lines.join('<br/>'));
      buffer.scrollTop(lines*100);
      lines = lines + msg.lines.length;
    });

  })();
  </script>

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.