A Push Notification Relay System Using Node.js and Socket.io

Background

For one of the pet projects I’m working on, I really want to create a push notification system. The site itself is written with PHP using the Kohana Framework. This works great and was a super fast and easy way to get things up and running. However, as I found out, this system isn’t really conducive to the “push” notification system I wanted. I originally went with the tried & true method of long polling. Using an PHP/AJAX example I found, I got it working. But I knew this wasn’t really the ideal solution.

I did more searching around, and was reading about Web Sockets that are part of the HTML 5 spec. I eventually came across the node.js plugin Socket.IO. Now I was already using PHP and Apache for my web application, so I didn’t want to have to redo it all to be a node.js website. So instead, I set out to create “relay” system that clients could subscribe to and my PHP scripts could send notifications too. After playing around, it wasn’t too difficult to get working.

The General Idea

The general idea is that I wanted a node.js server running that I could make a call to containing my message, and it would repeat that message to call connected clients. To keep things simple, we are just going to put our message right in the URL and our node.js server can pull it out and pass it along. For example, if I want to send the message ‘test’, our URL will be

http://localhost:8080?message=test

The Server Part

So our node.js script is going to look like the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var app = require('http').createServer(handler)
  , io = require('socket.io').listen(app)
  , url = require('url')
 
app.listen(8080);
 
function handler (req, res) {
	// parse URL
	var requestURL = url.parse(req.url, true);
 
	// if there is a message, send it
	if(requestURL.query.message)
		sendMessage(decodeURI(requestURL.query.message));
 
	// end the response
	res.writeHead(200, {'Content-Type': 'text/plain'});
	res.end("");
}
 
function sendMessage(message) {
	io.sockets.emit('notification', {'message': message});
}

It should be easy to follow what is going on. The ‘handler’ function handles all incoming connections to the server. Using the URL node.js plugin, we can parse the URL for the GET parameter we want (in this case, ‘message’). I run the message through JavaScript’s decodeURI function to clean it up (spaces would be specified by + or %20 in the URL and other characters could be escaped), then send it to the clients.

The Client Part

1
2
3
4
5
6
7
<script src="socket.io.min.js"></script>
<script>
	var socket = io.connect('http://localhost:8080');
	socket.on('notification', function (data) {
		console.log(data.message);
	});
</script>

This part just connects to our server and listens for notifications. When a notification is received, it’s just written to the console.

Afterthought

Hopefully this will be useful to some people out there. Obviously there are some flaws with this solution. The biggest being that anyone that knows the URL can send any messages to your clients. So you would probably want to figure out some way to lock that down. But that is beyond the scope of this post.

Posted in Web