Click here to Skip to main content
Click here to Skip to main content

Web Browser Compatible Comet & Websocket Service

By , 2 Jul 2011
 

Introduction

A few months ago, I wrote a web communication application for a company competition based on an HTML5 feature: websocket. No wonder, websocket will become a very popular and useful way for web based communication and it turns out that windows based client applications can be replaced more and more by web based client applications because of the websocket's arrival. However, there is the reality that not all web browsers support websocket so far. In order to be compatible to the old way, our pure web based application with websocket support cannot be released to the market because most people are using IE (it looks like IE9 supports websocket). Especially in China, IE6 users are everywhere. It makes me feel very bad that people with websocket support web browser are not able to use the advanced feature. Therefore, of late, I'm doing one job to combine comet and websocket together to implement web based communication.

Comet is one old but mature way to do web based communication with AysHttpRequest. I'm not going to introduce how to implement comet in this article. You can find lots of articles in CodeProject or you can simply have a look at my source code.

Please check:

What I'm doing is to open a comet communication service as well as websocket service on server with the same interface to client connection. Client will automatically select the proper service in terms of the client web browser. Then you can take care of your business data and send the data between web browser and server without considering what web browser you are using.

Using the Code

Server Side

Basically, the server side classes structure is like below:

serverConnection.PNG

WebsocketServer and CometServer manage their own connections respectively. WillWebCommunicator takes the responsibility to distribute messages between different services. For example, if there has one message sent from one user.

IWillCommunication will bring up messageArrived event no matter whether the message is from Websocket or comet. WillWebCommunicator will capture this event.

public static void CreateWebSocketService(int port, string origin, 
	string location, int maxlinks = 100)
        {
            IWillCommunication communicator = new WebSocketServer(port, origin, location);
            communicator.Start(maxlinks);
            communicator.ClientMessageArrived += 
		new ClientMessageHandle(communicator_ClientMessageArrived);
            communicator.Connected += new ConnectionEventHandle(communicator_Connected);
            communicator.Disconnected += 
		new ConnectionEventHandle(communicator_Disconnected);
            _Connections.Add(communicator);
        }
        public static void CreateCometService(int maxlinks = 100)
        {
            if (_Connections.Contains(CometServer.Instance)) return;
            _Connections.Add(CometServer.Instance);
            CometServer.Instance.ClientMessageArrived += 
		new ClientMessageHandle(communicator_ClientMessageArrived);
            CometServer.Instance.Connected += 
		new ConnectionEventHandle(communicator_Connected);
            CometServer.Instance.Disconnected += 
		new ConnectionEventHandle(communicator_Disconnected);
        } 

and determine the message is going to be sent to one particular user or all users from WillObject.To:

if (obj.To == "*")
{
    WillWebCommunicator.SendToAll(message.FromJson());
}
else
{
    WillWebCommunicator.SendToOne(obj.To, obj);
}

In WillWebCommunicator.SendToAll, message will be sent to all users both in Websocket server and comet server to make sure everyone get the message.

public static void SendToAll(string message)
{
    foreach (IWillCommunication communicator in _Connections)     
	communicator.SendToAll(message);
}

In WillWebCommunicator.SendToOne, we will search both websocket server and comet server to locate the right user. There is a Token property to indicate one particular user with GUID, this token will be created when user connects to the server for the first time.

public static void SendToOne(string token, string message)
{
   foreach (IWillCommunication communicator in _Connections) 
		communicator.SendToOne(token, message);
} 

Client Side

In order to make end users use remote service without considering the client webbrowser, I wrote a "communicator" singleton object to encrypt the connection to service. There 3 basic events in this object: ServerConnectedEvent, ServerDisconnectedEvent, MessageArrivedEvent. Through these 3 events, the final user is able to communicate with server side. If we look at communicator object from object oriented perspective (we didn't really create a class here, the object is created from asynomus function), we can simply assume there are actually 3 classes in the model: baseService, willCometConnection, websocketConnection.

clientConnection.PNG

I override open, close, send methods with respective behavior in comet and websocket. The "communicator" object will determine which real object will be applied with the below code:

if ("WebSocket" in window) return willSocket();
else return willComet();

Another configuration object keeps the comet connection string as well as websocket connection string.

var configuration = function () {
    return {
        websoketConnstring: "",
        cometConnstring: ""
    }
} ();

The final user will call the objects like below:

configuration.cometConnstring = "CometConnection.ashx"; 
configuration.websoketConnstring = "ws://127.0.0.1:8181/WillSocket"
communicator.addMessageArrivedEvent(messageArrived);//messageArrived is your 
				//method to react MessageArrived event
communicator.open();

The simple thing you need to do next is to fill your messageArrived method, run your application and see the magic.

How to Use the Demo

Run up your willwebcommunication website in your VS2010 or (IIS needs some configuration, U suggest you run it in VS2010). If your computer is in the network, don't forget to change websocketConnstring to your IP address.

configuration.websoketConnstring = 
	"ws://127.0.0.1:8181/WillSocket" //change your ipaddress 

Visit Default.html both in IE and Chrome to make sure you opened one comet connection and a websocket connection. In both webpages, you can find the other one's token beginning with "Comet" or "Websocket", click the right one to send a message by clicking the button. (Sorry for the very simple demo. I will improve it soon.)

License

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

About the Author

WillCaptain
China China
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionExceptionmemberyousefk3 Sep '11 - 0:31 
AnswerRe: ExceptionmemberWillCaptain4 Sep '11 - 15:27 
GeneralMy vote of 4memberjfriedman22 Jun '11 - 6:03 
QuestionBug in checker_Elapsedmemberjfriedman22 Jun '11 - 6:03 
AnswerRe: Bug in checker_ElapsedmemberWillCaptain22 Jun '11 - 19:07 
Questiondemo not workingmemberMember 404996320 Jun '11 - 16:06 
AnswerRe: demo not workingmemberWillCaptain20 Jun '11 - 18:37 
AnswerRe: demo not workingmemberWillCaptain22 Jun '11 - 19:19 
GeneralMy vote of 5memberm3tano20 Jun '11 - 3:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 2 Jul 2011
Article Copyright 2011 by WillCaptain
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid