5,136,034 members and growing! (12,361 online)
Email Password   helpLost your password?
Web Development » ASP.NET » General     Intermediate License: The Code Project Open License (CPOL)

ASP.NET & Comet: Bringing Sockets back

By Wilfred Verkley

Implementing a socket based Comet solution in ASP.NET
C# (C# 3.0, C#), JScript, HTML, Windows, .NET (.NET, .NET 3.5), ASP.NET, Dev

Posted: 9 Apr 2008
Updated: 9 Apr 2008
Views: 4,164
Announcements



Search    
Advanced Search
Sitemap
11 votes for this Article.
Popularity: 4.85 Rating: 4.65 out of 5
0 votes, 0.0%
1
0 votes, 0.0%
2
0 votes, 0.0%
3
3 votes, 50.0%
4
3 votes, 50.0%
5
Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report This Article

Sample Image

Introduction

Web pages and ASP.NET are a wonderful tools, but as the old proverb goes, "if all you have is a hammer, everything seems like a nail". ASP.NET is a web technology, all of which exists to serve up resources to Web Browsers which request them. Thats great, and it works for the vast majority of things currently on the internet. In fact, when people think of the internet, they mostly associate it with the ubiqitous world wide web model or its HTTP protocol. But what if we want more...what if instead of Web Browsers just requesting resources, we want to push information actively out to them, without being asked first. Examples of this include; live wiki's, polls, chat, stock tickers, real-time auctions, and games.

This is where the existing paradigm fails, and we have to fall back to older technologies, the roots on which the internet is founded....yes, im talking actual two-way communication, interactivity, *gasp* sockets, TCP/IP!

Taking a step back, web requests can roughly be compared to a student asking a teacher questions. However, only the student is allowed to ask questions, the teacher cannot actively prompt the student with facts. This article sets out one experimental aproach to breaking that model. Most of the current solutions, collectively called "Comet", involve the Web Browser keeping a active HTTP connection to the Web Server, like a student always keeping the teachers attention. Presented here is another aproach, utilizing a "side-channel", where the "teacher" (thats the Web Server) doesnt spend as much attention or resources responding to pesky questions (web requests), and we can push information out instead, or engage in a more interactive way.

Background

This article is inspired and partially based on the work and code by Alex MacCaw, the developer who created the Juggernaut extension to Ruby on Rails. But why leave all the fun to those dymamic language people? Cant we have that in ASP.NET too? The answer is "yes we can."

How do we communicate with the Web Browser without it making a request first? One solution is to have the Web Browser keep open a socket connection directly to the server using a small light-weight Flash component.

What are the benefits of this aproach:

  • It consumes much less Web Server resources. We are not dedicating any Web Server threads to responding to a "long-polling" request.
  • Its simple and easy to implement.
  • Good cross-platform support (any modern Web Browser that supports Flash 8 e.g. IE, FireFox, Safari, Opera)
  • Lower latency, no re-establishing connections, or other HTTP protocol overhead.

And yes, it does have drawbacks:

  • We need to install something on the Web Server or network domain to accept these socket connections.
  • The embedded Flash component making the connection to the Comet Server will not work behind firewalls or proxies that block non-HTTP ports.
  • It needs Flash and javascript enabled on the Web Browser.
  • Its a hack (though the same thing could be said about many now ubiquitous Web Browser technologies).

Using the Code

Comet applications can be divided into two categories:

  • "Server-push" applications where the Web Server pushes out information on updates and changes based on user events e.g. live wiki's, polls, chat.
  • "Interactive" applications where an external process pushes information to the web browser in response to any type of event e.g. stock tickers, real-time auctions, games.

Server-push

The work flow of using Comet in server-push scenario is:

  1. The Web Browser requests a page of the Web Server, which includes the Flash Comet component, Comet javascript, and a unique authentication string.
  2. The Web Server registers the Comet connection with the "Comet Server", specifying its channel, its authentication string, and any initial state.
  3. The Web Browser opens a socket connection to the Comet Server, and sends its authentication string.
  4. The Web Browser sends data to the Web Server using postbacks.
  5. The Web Server responds to any postbacks or AJAX calls and publishes any updates to the Comet Server
  6. The Web Browser responds to any updates from its Comet connection

In code with a simple "GuestBook" example:

  1. Placing a "CometControl" on the ASP.NET web page:
    <CometControl
        id="cometControl"
        runat="server"
        channel="GuestBook"></CometControl>
  2. Registering the Comet connection:
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            cometControl.Register();
    }
  3. Opening a socket is done automatically on the Web Browser if the "AutoConnect" property is set to true (the default).
  4. Ajax postbacks can be done with a simple update panel using the ASP.NET AJAX extentions.
  5. The Web Server responds to AJAX events by publishing javascript code that is automatically eveluated on the Web Browser.
    protected void submitButton_Click(object sender, EventArgs e)
    {
        string name = nameTextBox.Text.Trim();
        string text = commentTextBox.Text.Trim();
        if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(text))
        {
            cometControl.Data = "guestbook_addComment ("
                + Wxv.Comet.Utility.SerializeJSON(
                    HttpContext.Current.Server.HtmlEncode(name))
                + "," + Wxv.Comet.Utility.SerializeJSON(
                    HttpContext.Current.Server.HtmlEncode(text)) + ");";
            cometControl.Publish();
        }
        commentTextBox.Text = "";
    }
  6. Finally, the Web Browser recieves the data published on the Web Server and executes it:
    guestbook_addComment = function(name, comment)
    {
        var commentsDiv = document.getElementById ("comments");
        var e = document.createElement("blockquote");
        e.innerHTML = comment + " - " + name + "";
        commentsDiv.insertBefore (e, commentsDiv.firstChild);
    }

Interactive

The interactive scenario is very similar but instead of the Web Browser doing postbacks or AJAX calls to the Web Server, the Web Browser is using its Comet Connection to send data directly to an Application Client and vice versa.

The work flow of using Comet in interactive scenario is:

  1. The Web Browser requests a page of the Web Server, which includes the Flash Comet component, Comet javascript, and a unique authentication string.
  2. The Web Server registers the Comet connection with the "Comet Server", specifying its channel, its authentication string, and any initial state.
  3. The Web Browser opens a socket connection to the Comet Server, and sends its authentication string, and the Comet Server tells any Application Clients whether a connection has been made if on a channel they have subscribed to.
  4. The Application Client sends data to the Comet Server, which passes it onto any Web Browsers which have are connected on that channel.
  5. The Web Browser sends data to the Comet Server over its Comet connection, which passes it onto any Application Clients which have subscribed to that channel.

The Web Browser code is still very similar, but now instead of doing AJAX calls or postbacks, we can just send data to our actively listening Application Client over the Comet connection.

e.g. in response to a button click in a "sound player" application:

function sounds_click(soundId)
{
    comet.send (soundId);
}

The Comet Server and Clients

The Comet Server is a simple event handling and messaging component that accepts two types of connections:

  • Comet connections from Web Browsers. These are always pre-registered and associated with a single channel.
  • Client connections from the Web Server CometControls or Client Applications.

It responds to the following Client events:

  • Register - A Client wants to allow a Web Browser to make a Comet connection.
  • Subscribe - A Client wants to listen to events on a specific channel.
  • Publish/Push - A Client wants to send data to an entire channel (Publish) or a specific Comet connection (Push).

It sends the following events to any Clients that have subscribed to the related channel.

  • Connect - A Web Browser has successfully connected and authenticated with the Comet Server.
  • Disconnect - An authenticated Web Browser has disconnected from the Comet Server.
  • Send - A Web Browser has sent data to the Comet Server.

Both the Comet Server and the Client component, which Application Clients can be written with, are simple components. The Comet Server component is self-contained, the only interaction needed is to get it to start and stop, and it can be easily be hosted in a windows application, a service, or even in the Web Server itself. Similarly, the Client is a simple component (which the CometControl already encaptulates) which exposes some simple methods and events (on a single thread) which can easily be extended to write your own Application Clients which can also be hosted in a variety of ways.

Summary

Web browsers opening socket connections to a server isnt actually that new. In their isolated little sandboxes, Java applets have been doing it since they were invented more then a decade ago, and Flash has had the capability for while too. Microsoft's Silverlight will eventally be getting it in version 2.0. All the Comet aproaches are trying to do is get a similar capability directly within the web browser itself.

Ive had fun with this project, exploring one Comet solution for ASP.NET. I dont pretend that its anything more than it is, a toy project, so consume and eat it with a grain of salt (and credit me if tastes nice). For this author however, it gave an interesting insight to whats possible.

History

7-Apr-2008 - First version!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Wilfred Verkley


Im a Software Developer working in Auckland, New Zealand. When i was a lot shorter, i started programming in Atari Basic, though these days its mostly C#, and a bit of java (mostly the caffinated kind).
Occupation: Web Developer
Location: New Zealand New Zealand

Other popular ASP.NET articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 13 of 13 (Total in Forum: 13) (Refresh)FirstPrevNext
Subject  Author Date 
QuestionRunning Comet server as a console applicationmemberravi_sapra2:04 15 May '08  
AnswerRe: Running Comet server as a console application [modified]memberWilfred Verkley3:59 15 May '08  
GeneralLove It...ACT?memberjabailo17:10 9 May '08  
GeneralRe: Love It...ACT?memberWilfred Verkley20:32 9 May '08  
GeneralIt is all based on http requests and responsememberDev_Calz3:48 20 Apr '08  
GeneralRe: It is all based on http requests and responsestaffAdam Smith13:17 20 Apr '08  
GeneralRe: It is all based on http requests and responsememberWilfred Verkley14:30 20 Apr '08  
GeneralHeystaffAdam Smith20:55 18 Apr '08  
GeneralRe: HeymemberWilfred Verkley21:25 18 Apr '08  
GeneralHTTP?memberBalamurali Balaji1:37 18 Apr '08  
GeneralRe: HTTP? [modified]memberWilfred Verkley3:28 18 Apr '08  
GeneralReally fantastic ideamembervkuttyp8:43 9 Apr '08  
GeneralRe: Really fantastic ideamemberwxv22:55 9 Apr '08  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 9 Apr 2008
Editor:
Copyright 2008 by Wilfred Verkley
Everything else Copyright © CodeProject, 1999-2008
Web18 | Advertise on the Code Project