Matt Hughes i like to grow tiny trees and tinker on stuff

Adventures with WebSockets and Socket.IO

Last week I started working on a method to send a real-time message to a web browser to trigger an update with user data. The scenario I worked on goes like this:

  1. User A (belonging to a group) is logged into a web application.
  2. User B, the group's admin, updates permission settings for that group.
  3. User A's browser would be notified real-time of the update and get the new permission settings behind the scenes.

I've heard lots about using socket.io for sending real-time messages over HTTP, and it was the first project I worked on. It is a great framework that uses WebSockets, and supports other protocols as a fallback.

The feature that really met to my needs is the emit method. This allows socket.io to send custom events, not just the message event. By limiting the events that a client listens on, you can only receive relevant messages.

Most socket.io examples are chat applications. They're very lightweight and illustrate how to send messages from client-to-server, and server-to-client. Each user's browser will use socket.on('event', function{...}); to listen for a certain event. The server then will use socket.emit('event', data); to send the message to clients listening on that event.

My use case was a little bit different. When a user makes an update to their group settings, I wanted to send a socket.io message to all other users in the group that are logged in.

My code uses Express to listen for a POST, and uses socket.io to emit a message to trigger an update for all users in that group.

Basic API structure in app.js:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.patch('/user/:id', function (req, res) {
  console.log('PATCH: ' + req.url);
  //do user update here
  io.emit(req.params.id, 'UserUpdated');
  res.status(200).send({ message: 'User update accepted' });
});

http.listen(3000, function () {
  console.log('Listening on port 3000');
});

Javascript in index.html, listening for socket.io messages:

<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>    
<script>
  var socket = io('http://localhost:3000', { transports: ["websocket","jsonp-polling","xhr-polling","polling"] });
  var user = 12345;
  socket.on(user, function(msg) {
    console.log('socket.io: ' + msg);
    //perform an action based on the msg content
  });
</script>

Download the full source at GitHub: https://github.com/GenBurnside/socket.io-express-skeleton