Skip to content

Instantly share code, notes, and snippets.

@jchillerup
Created January 12, 2012 22:03
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save jchillerup/1603424 to your computer and use it in GitHub Desktop.
Save jchillerup/1603424 to your computer and use it in GitHub Desktop.
remote reloading of web content with socket.io and node
var socket = io.connect('http://HOSTNAME:8080');
socket.on('reload', function (data) {
location.reload();
});
/*
socket.on('eval', function(data) {
eval(data.evalString);
});
*/
var io = require('socket.io').listen(8080);
var http = require('http');
io.sockets.on('connection', function (socket) {
// nothing currently
});
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Reloading clients\n');
io.sockets.emit('reload', {});
}).listen(1337, "HOSTNAME");
console.log('Server running at http://HOSTNAME:1337/');
@jchillerup
Copy link
Author

Maybe, for the eval thing, it'd be prettier to just pass a callaback instead of evaluating strings. It's a TODO!

@pmuellr
Copy link

pmuellr commented Jan 13, 2012

I could see this being tool-ized. Here's a sketch.

In a web page, include reloader.js, then execute

reloader.check(updateURL)

Where updateURL is a URL specific to this web page/app.

On the server side is a command reloader. It has two activities, determined by command-line paramters.

  1. run as a server
  2. mark an updateURL as updated

Presumably still using web sockets. The server does a watch on a file reloader.updateURLs.json. That file contains a lastUpdated property for all the updateURLs that it knows about. When a 'mark an updateURL as updated' occurs, it updates the relevant entry, which the server then notice, re-read the file, send the appropriate notification to the relevant waiting web sockets.

Any interest in working on this? If not, I may start something myself ...

@jchillerup
Copy link
Author

Hello internet stranger!

Sounds pretty good. I think what you're suggesting is something different from my use case (debugging, primarily).

As I understand it you want to be able to remotely cause kiosk displays etc. to reload when there's new data, instead of interval refreshing with meta tags and what-have-you. I suppose you'd want to have a Node app running on the server side which this reloader app talks to.

Remember that you can enable callbacks in socket.io such that you can get a confirmation of a properly received packet. This will reduce the amount of uncertain lastUpdated rows in your DB.

Thanks for the interest in this little hack. If you're going all the way with the reloader thing, I'd be happy to contribute code.

JC

@pmuellr
Copy link

pmuellr commented Jan 13, 2012

No, this is not for production mode (kiosk), it's for development mode.

See my wr project. It continuously rebuilds my projects. I thought it would be nice, during my project build, if I could signal to a web page from that project, that's open in the browser, that it should or can reload, or that it just reload itself without asking. That removes another step from:

  • edit code in text editor
  • save code
  • build code (wr does this step now)
  • switch to browser
  • reload page (this tool will do that step now)

If the page I'm viewing are my test cases, then whenever I save, the tests are rerun, which is probably exactly what I want to be doing.

@pmuellr
Copy link

pmuellr commented Jan 13, 2012

In fact, I don't even need to "switch to browser", I just need to be able to see it, in most cases.

Now, if only I can automate the "edit code" and "press the save key" steps, I can retire.

Another way to do this would be to run a test server, have the build open a browser window on the tests served by the test server, have it run the tests, and send the results back to test server, which would be reported as success/failure of the build, along with any relevant messages. Then close the window.

For some reason, I think someone's done something like that before.

@jchillerup
Copy link
Author

Oh! Now I totally get it. Then it'd make sense to make a hook in wr that could call a function when it's done building. This function could then do whatever is needed to reload the browsers. If you take the code as-is from this gist, you can cause all clients to reload by running curl http://HOSTNAME:1337/ or wget if you prefer.

However, I do agree that it would be nice with something a little more polished. Also something that required the reloader app to auth to the server that the clients are listening to somehow. A challenge/response system with a shared secret would probably do for that. Sounds like a Sunday morning project :-)

@jchillerup
Copy link
Author

For unit testing you could look at BusterJS(.org). I haven't tried it, though, so I don't know much about it.

Also, I simplified the gist code somewhat. Apparently socket.io already had built-in broadcast capability. As an added bonus, we won't have lingering records of old sockets in the allsockets array that used to be there.

@pmuellr
Copy link

pmuellr commented Jan 13, 2012

I don't see it as a hook to wr, at least yet, but a standalone command I would add to my Makefile. If I ever server-ize wr, then I think maybe it would make sense to add it there, somehow.

w/r/t auth. Nope. I'd say, for the first pass, no auth, but you only run the server so it accepts connections from localhost. Safe enough. The biggest security hole would be shipping your code with the reloader script still in it. People have shipped pages in production that included the weinre target bits, which is the same, horrendous, security exposure. Or an awesome hack, whatever your tastes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment