Transform your IIS into a real-time pub/sub engine with Faye-Node

Faye is a simple Http Pub/Sub server initially implemented by John Coglan in Ruby, and also later ported by himself to Node.js. The version for Node.js implements the Bayeux protocol, which at first glace, many of us known as http long polling.

This project just represents another alternative to Socket.IO, which also works for client applications that are not necessarily implemented within a web browser.  As many http pub/sub engines out there, Faye also uses the idea of channels for routing messages, and it ships with two message repositories out of the box, a repository that runs in memory and a repository that stores the messages in REDIS.

On other hand, we have “IISNode”, one the coolest projects announced by Microsoft to host Node.js applications in IIS. One of the things you can do with IISNode is to run websites implemented with express or connect, and Faye can also be attached to an application implemented with connect, so we can this use this common denominator to mount a Faye server with IISNode.

This is also relatively attractive if you want to run your own pub/sub server in Windows Azure using IISNode as it was announced today

The code for the Faye server looks as follow (server.js),

var faye = require('faye'),
       connect = require('connect');
var server = connect.createServer(
    connect.staticCache()
);
  
var ROOT_ADDRESS = '/node/faye-node/myapp/';
 
server.use(ROOT_ADDRESS + 'static', connect.static(__dirname + '/static'));
server.use(ROOT_ADDRESS, function(req, res) {
  res.setHeader('Content-Type', 'text/html');
  res.end(process.env.PORT);
});
 
var bayeux = new faye.NodeAdapter({mount: ROOT_ADDRESS + 'faye', timeout: 45 });
 
bayeux.attach(server);
 
server.listen(process.env.PORT);

A few things to notice here,

  • The listen port is provided by IIS through the PORT environment variable.
  • The application is hosted in IIS under the virtual directory “node/faye-node”, and “myapp” is just a mapping I defined for the application using connect.
  • The Faye server is configured to listen to request messages on “node/faye-node/myapp/faye”

If you take a look at the web.config file for this application, the URL routing module is used to redirect all the traffic to “myapp” to this node application (server.js)

<configuration>
  <system.webServer>
 
    <!-- indicates that the hello.js file is a node.js application 
    to be handled by the iisnode module -->
 
    <handlers>
      <add name="iisnode" path="server.js" verb="*" modules="iisnode" />
    </handlers>
    
     <rewrite>
      <rules>
        <rule name="myapp">
          <match url="myapp/*" />
          <action type="Rewrite" url="server.js" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

Once you have the server up and running, you can configure several clients to send or subscribe messages to/from the Faye server. This is how a client application implemented in Node.js looks like,

var faye = require('faye');
 
var client = new Faye.Client('http://localhost/node/faye-node/myapp/faye',{
     timeout: 120
 });
 
client.subscribe('/one', function(message) {
    console.log('something received: ' + message.result );
 });
 
var publication = client.publish('/one',{ result: 'other message from one'});
 
publication.callback(function(){
    console.log('message sent');    
    client.disconnect();
});
 
publication.errback(function(err){
    console.log(err);
});
 

As you can see, the complete URL is used on the client side to connect to the server. A client for Faye can also be implemented within a browser,

<html>
  <head>
    <script type="text/javascript" 
        src="http://localhost/node/faye-node/myapp/faye.js">
        </script>
    <script type="text/javascript" 
        src="http://localhost/node/faye-node/static/jquery.js">
        </script>
  </head>
  <body>
    <script type="text/javascript">
      
      var client = new Faye.Client('http://localhost/node/faye-node/myapp/faye',{
        timeout: 120
      });
      
      function publish() {
    var publication = client.publish('/one',{ result: 'message from one'});
        publication.callback(function(){
          alert('message sent');
        });
      }
    </script>
    <span onclick="publish();">Click me!</span>
    <h1>Home.html</h1>
    <ul class="container">
    </ul>
  </body>
</html>

Faye will provide an URL for downloading the client library in the browser (myapp/faye.js).

Download the complete sample from here

Comments

No Comments