It begs the questions is there actually anything left in WPF that Silverlight now can’t do? It now even supports running outside of the browser!
Tuesday, 17 March 2009
In my previous post I discussed the merits of the COMET technique for pushing data to the browser over standard web protocols.
The basic idea behind COMET is that the browser keeps an HTTP connection open and the server uses it to send data back. This contrasts with HTTP’s Request/Response paradigm where the browser is specifically requesting data when it needs it. There are two main types of COMET – Streaming and Long-Polling. For Streaming COMET, the browser opens a single connection and keeps it open indefinitely, receiving events from the server when they are ready to be sent and immediately processing them. With Long-Polling, a connection is opened and is kept open until the server has data to send to the browser (or data is sent immediately if waiting). Once the data is received, a new connection is immediately opened which again blocks until data is ready to be received, and so on.
Over the last several years a protocol for COMET, known as Bayeux, has been formalised by the dojo foundation. The protocol specifies the wire format for messaging between client and server as well as the transport mechanisms involved, and supports both streaming and long-polling over standard HTTP transports. It’s essentially a specification for a pub/sub message bus, where clients can publish messages to channels and subscribe to messages on those channels. A number of client libraries have support for Bayeux style comet messaging, most notably the Dojo Toolkit.
There are also a number of server frameworks for COMET out there, including one from Dojo themselves – cometd - which implements Bayeux and integrates with their client framework. There are also commercial COMET servers out there, such as LightStreamer and Liberator, which actually offer .NET integration and support for integrating with enterprise messaging systems such as Tibco RV. However, searching around I have been unable to find any that run within ASP.NET (well definitely not free ones anyway) and I think it’s a very important thing to support within ASP.NET - custom servers are fine, but you can’t exactly run them on shared hosting providers!
One of the main challenges to developing a COMET server which runs within IIS is the threading model of ASP.NET (I believe Apache has the same issues, but not sure). With ASP.NET, each request is serviced by a single thread from the thread pool. This basically rules out being able to support Streaming COMET, as we would have to keep a thread aside for each client, and there a limited number of threads in the thread pool. So this leaves the Long-Polling option. This is wholly possible within ASP.NET as it has support for asynchronous processing, meaning we can put the thread back on the thread pool until we actually have data to send back to the client.
And this is what I am working on now. The project is called AspComet and is available at the AspComet Google Code Website via SVN. It’s pretty basic at the moment and it just supports a small test case, however it’s built against the Bayeux spec and therefore can be used with any client library which supports Bayeux (I am testing with dojo of course).
In the next post, I will describe a bit about how it works and walk through a sample simple chat application built using it.
Saturday, 7 March 2009
So a bit of background here. Traditional “AJAX applications” often continually poll for changes and update the screen accordingly. In fact, in ASP.NET, a very easy solution is to combine an asp:Timer class with an asp:UpdatePanel and simply re-render the changing content every few seconds and send back the updated HTML. Taking this to a more advanced level, it’s possible to send data back to the browser (typically as JSON) and then use DOM manipulation to update the elements viewed on the screen.
To give a more concrete example, imagine a simple “chat room” application. A simple solution could be to render a div with the list of chat messages in it, wrapped in an UpdatePanel, and then provide a text box for entering chat messages. When the user presses “enter” within the textbox, an AJAX request is made to send the message back to the server, and the server adds this message to the list of chat messages. The update panel can then be refreshed using a timer.
What are the problems with this? Two things – scalability and latency.
Firstly, we are sending back the rendered HTML each time - this is not the most efficient use of bandwidth (i.e. each chat message is likely wrapped in a few elements). Secondly, every time the UpdatePanel is refreshed, the entire chat history has to be sent back. As this grows this will be become problematic as the amount of data being processed and sent over the network will increase exponentially with the number of users contributing to the chat. Finally, as we are polling (say once every 5 seconds) there is a lag involved between when a user enters a chat message and when another user receives the message. These are potentially not major issues, but in this day and age the average web user’s expectations are quite high - they expect lightweight, fast and responsive web user interfaces!
Once you have JSON objects coming back to the browser, the second issue becomes easy to solve. The browser can send back the ID of the last message it received, and the server only needs to send back those messages which were received after that.
It’s when we try to resolve the latency issue that the this technique becomes problematic. The only real solution using plain old polling is to increase the polling frequency, which leads to a huge waste of server resources.
So we come back to COMET, which is a technique (some might say hack, but I disagree) of pushing data to the browser using standard HTTP requests. There are alternatives to this approach, namely using browser plugins. Flash and Silverlight both have support for raw sockets, and Silverlight has the “polling duplex” WCF transport (which I may discuss in a later post). However, COMET is a solution which has been designed from the ground up to use standard web technologies and run over HTTP. I will discuss the technical details of COMET further in the next post… this post is really just an introduction and to point out that I have started working on a project which will enable COMET via ASP.NET hosted in IIS!
More to come…