The integrated architecture means that the webapplication and WebSync Server run in the same IIS pool. In Azure this means you can spin up a new instance when the running instance(s) run out of resources.

Isolated Application Architecture:

Img 02: Isolated Application Architecture WebSync

The isolated architecture means that the webapplication and WebSync Server run in separate IIS application pools. At this moment in time we implemented the integrated architecture, but we are debating if we need to go for the isolated architecture, we think it is more robust and gives us the opportunity to decouple the real-time, or notification logic even more.

ROBIN Deployment Architecture We have the following deployment architecture:

Img 03: ROBIN Deployment Architecture

As image 03 shows we use the integrated architecture, realtime is part of our Process Services layer. In our Frontends, API’s and Background Worker layers we leverage Websync to do the real-time handling for us.

Storage ProviderWebSync needs storage, and supports the following providers out-of-the-box:

Sticky Providers

In Memory Provider (Default)

Sticky Sql Provider

Stateless Providers

Stateless Sql Provider

Azure Table Provider

We use the Stateless Sql Provider, because it is the fastest provider WebSync supports that works on Azure. We already had an on premise working version that used the Sticky SQL Provider, switching seemed the easiest. We think switching to the Azure Table Provider will be easy and we will do this if we need it for scalability reasons, we would like to avoid this because we want the best performance possible.

Database deployment script (we do not want WebSync to generate the tables it needs in our production environment)

Configuration (web.config for the most part, we really want to leverage Azure’s ServiceConfiguration for this, but webSync does not support it at this moment)

Server-side publishing

Client real-time handling

Database deployment script and configurationThe database deployment was easy, because WebSync can generate the tables for you (default). The only thing we had an issue with, is that if you do not want WebSync generating the tables, but create them yourself, you have to add that in config. you have to use the manageSchema atrribute:

Server-side publishingOn the server-side we lean heavily on Inversion of Control or Dependency Injection. We find it is real helpfull to compose our objects as we see fit, and it also helps tremendously in our TDD workflow. Because we need to support al kind of clients (webapplications, iPhone, other mobile devices) we evolved to the following (simplified) implementation:

Ofcourse, our implementation consists of more, but this, in short, is how we wrap WebSync. We got a RealtimeService (which implements IRealtimeService)and have the notion of 'Publisher', for every frontend (webapplication, device) we have a Publisher implementation, we inject these using Dependency injection. It makes us really flexible. For every new Publisher type we only have to create a new Publisher implementation, or leverage an existing one.

Client real-time handlingOur main webapplication has a ‘one page architecture’, we have a single page and use Javascript to show different parts of the application on that page. We use module and jquery widget factory patterns. We are looking into backbone, ember and knockout. We have the notion of a ‘Communicator’ in our clientside architecture. In the Communicator we handle the subscriptions and all incoming real-time (push) messages.

As you can see in listing 04 the communicator also uses a jQuery plugin for pub/sub. This plugin makes it possible to use the publish-subscribe pattern throughout our modules and widgets. This plugin uses topics to differentiate between publications. Whenever a real-time message is pushed from the server, a $.publish(…)event for a particular topic is fired and all subscribers to this topic will recieve the message.

I made the listings as small as possible, to show the intend. The WebSync client api is clean and self explaining. You have to init, than connect and subscribe. We have lots of advantages from using WebSync, the administration of what clients are connected to which subscriptions is abstracted away for the most part. The way WebSync handles all browsers is a big benefit also, we implemented WebSockets ourselves and had to do all that work manually untill now.

Because we think it is very important to serve our users changes and notifications in a real-time fashion, we evaluated a lot of tools, components to achieve this. First we looked at Socket.IO, NowJs and Node.js, but we soon found out that this is not very hard if your team is used to Microsoft tooling. Since the ROBIN frontend (we call it the Agent Desktop) is a web application that is built using the Microsoft stack, we need a framework that is better integrated with the stack we know.

Azure and other considerations

We run ROBIN on Azure which added another complexity. We started out using raw Websockets and used Nugget where we only targeted the newest browsers like Chrome and Firefox, but as soon as the websocket specs evolved Chrome did no longer supported our version and Firefox did not support websockets anymore. So we did an evaluation of real/time Comet frameworks that work with .NET. This was before SignalR existed.

We found that while Websync and Pokein did not support websockets at the time, they handled Comet really well. We knew that WebSyncwill support websockets as soon as the specs are official and browsers are supporting these official specs. We found that WebSyncwas more mature, they are robust and their api’s are well documented, although they are more expensive they are most mature also. We found that the google group they use to communicate with their community is very responsive, they will help you as soon as they can. Whenever we had an issue they helped us and the issue was fixed quickly up to now.

Implementation We implemented WebSync and are using it in production for a while now, we also have an iPhone app that uses WebSync. This was easy, because they provide iOS examples.

Things to improveWe find that Azure integration works, but can be done better. The configuration of the database (WebSyncneeds four tables in a database) is handled in web.config. When working in azure ServiceConfiguration is preffered, but not supported by WebSync at this moment. So all instances need a configutred web.config and serviceconfigs will not work. SQL Azure is supported and Azure Table Storage can be used for WebSync storage also, but performance is better on SQL Azure.

ConclusionAll in all, we are very pleased with WebSync, it abstracts the real-time communication away and works really well for us. We hope to grow together with WebSync to a real-time enabled future for ROBIN!