How to Use Socket.IO with Azure Mobile Service Node Backend

Mobile communications and social networking concept

With Azure Mobile Service .NET backend you can do realtime communication using SignalR however such an option was not available for our node backend customers. With the latest update of Azure Mobile Service node backend, we’ve made it easy for you to hookup socket.io with your Mobile Service.

Installation

First of all clone your Mobile Service git repository locally like so:

C:\> git clone <a href="http://YOUR-SERVICE-NAME.scm.azure-mobile.net">http://YOUR-SERVICE-NAME.scm.azure-mobile.net</a>

Then change your directory to ‘service’ folder and install ‘socket.io’ module

cd nodetestapp\service
npm install socket.io --save

Note: To avoid pushing the node_modules folder in your remote repository, you have to add the .gitignore file. See Support for package.json in Azure Mobile Services for details.

Now change your directory to ‘extensions’ folder and create a file called ‘startup.js’ with following contents:

var path = require('path');

exports.startup = function (context, done) {
	var io = require('socket.io')(context.app.server);
	io.on('connection', function(socket){
	  socket.on('chat message', function(msg){
		io.emit('chat message', msg);
	  });
	});	

       context.app.get('/public/chat.html', function(req, res) {
		res.sendfile(path.resolve(__dirname, '../public/chat.html'));
	});	
	done();
}

In the snippet above we configured socket.io and added a route to host our chat app.

Chat app

Create a new file ‘chat.html’ and put it in a new folder called ‘public’ inside the ‘service’ folder with following html:

<!doctype html>
<html>
  <head>
    <title>Socket.IO chat</title>
    <style>
      * { margin: 0; padding: 0; box-sizing: border-box; }
      body { font: 13px Helvetica, Arial; }
      form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
      form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
      form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages li { padding: 5px 10px; }
      #messages li:nth-child(odd) { background: #eee; }
    </style>
  </head>
  <body>
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
    <script src="http://code.jquery.com/jquery-1.11.1.js"></script>
    <script src="http://cdn.socket.io/socket.io-1.0.0-pre5.js"></script>    
    <script>
      var socket = io();
      $('form').submit(function(){
        socket.emit('chat message', $('#m').val());
        $('#m').val('');
        return false;
      });
      socket.on('chat message', function(msg){
        $('#messages').append($('<li>').text(msg));
      });
    </script>
  </body>
</html>

Finally commit all your changes and push them up to your Mobile Service using add, commit and push commands of git.

Then visit http://YOUR-SERVICE-NAME.azure-mobile.net/public/chat.html and you’ll see a page that shows you a text box and a button at the bottom. Open two instances of this page in the browser. Type a message and press enter. You’ll see the message in the other window too.

Scale out

The above sample works only when you have a single instance of your Mobile Service. If you have multiple instances then you’ll need to use redis as a backing store for your realtime communication along with socket.io. For that you can install the socket.io-redis node module from npm

https://www.npmjs.org/package/socket.io-redis

And you can configure it to work against your redis instance in Azure. See the following article for details:

http://azure.microsoft.com/en-us/documentation/articles/cache-dotnet-how-to-use-azure-redis-cache/