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

DotNet WebSocket Programming

By , 8 Aug 2012
 
 Download Sample Code here

What is WebSocket 

Recently, there has been a lot of buzz around HTML5 and Web Sockets. Web Socket defines a full-duplex communication channel that operates through a single socket over the Web. It is not just another incremental enhancement to conventional HTTP communications; it represents a colossal advance, especially for real-time, event-driven web applications

Where WebSocket works 

Normally when a browser visits a web page, an HTTP request is sent to the web server that hosts that page. The web server acknowledges this request and sends back the response. It is simple, we know about that. But, the challenge is how do you process "real time" information in web.

ClientServer

Solution1 - Polling

With polling, the browser sends HTTP requests at regular intervals and immediately receives a response. This technique was the first attempt for the browser to deliver real-time information. Obviously, this is a good solution if the exact interval of message delivery is known, because you can synchronize the client request to occur only when information is available on the server.

However, real-time data is often not that predictable, making unnecessary requests inevitable and, as a result, many connections are opened and closed needlessly in low-message-rate situations.

Solution2 - Long Polling

With long-polling, the browser sends a request to the server and the server keeps the request open for a set period. If a notification is received within that period, a response containing the message is sent to the client. If a notification is not received within the set time period, the server sends a response to terminate the open request.

However, that when you have a high message volume, long-polling does not provide any substantial performance improvements over traditional polling. In fact, it could be worse, because the long-polling might spin out of control into an unthrottled, continuous loop of immediate polls.

Solution3 - Streaming

With streaming, the browser sends a complete request, but the server sends and maintains an open response that is continuously updated and kept open indefinitely (or for a set period of time). The response is then updated whenever a message is ready to be sent, but the server never signals to complete the response, thus keeping the connection open to deliver future messages.

However, since streaming is still encapsulated in HTTP, intervening firewalls and proxy servers may choose to buffer the response, increasing the latency of the message delivery. Therefore, many streaming Comet solutions fall back to long-polling in case a buffering proxy server is detected

Better Solution - WebSocket

WebSocket

Web Sockets represent the next evolution of web communications - a full-duplex, bidirectional communications channel that operates through a single socket over the Web. From the above diagram, you can understand Web Socket is used to build scalable, real-time web applications.

How WebSocket works

To establish a WebSocket connection, the client and server upgrade from the HTTP protocol to the WebSocket protocol during their initial handshake response as:

GET /mychat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat
Sec-WebSocket-Version: 13
Origin: http://example.com
        

Then, server returns the below response. The handshake resembles HTTP, but actually isn't. It allows the server to interpret part of the handshake request as HTTP, then switch to WebSocket.

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
        

Once the connection is established, the client and server can send WebSocket data frames back and forth in full-duplex mode. They can send text frames in full-duplex, in either direction at the same time. The data is minimally framed at TCP layer.

WebSocket Tool-Kaazing

WebSocket is great, but what you can do once you have a full-duplex socket connection available in your browser is even greater. To leverage the full power of HTML5 Web Sockets, Kaazing provides a ByteSocket library for binary communication and higher-level libraries for protocols like Stomp, AMQP, XMPP, IRC and more, built on top of WebSocket.

Here is Kaazing WebSocket Gateway extends TCP-based messaging to the browser with ultra high performance:

Kaazing System

Environment Setup

Install pre-requiste like JVM, JDK, etc. All are open source items. We can download Kaazing WebSocket gateway from the web site http://kaazing.com/products/kaazing-websocket-gateway. Unzip the downloaded files in one of the local folder to run.

Run it

This product works on PubSub (Publish Subscribe) model and so we need to start Gateway as publisher and MessageQueue(ActiveMQ) as subscriber. Now, you execute the command from MS-DOS prompt.

Publisher

After starting the publisher, you start the subscriber engine as:

Subscriber

All set to go! Now, let us dwell into the implementation WebSocket communication in .NET environment.

C# Implementation

System Design

Kaazing WebSocket Gateway - JMS Edition uses the JMS API to extend the functionality of JMS providers. The Gateway includes JMS client libraries you can use to build a client for your application to enable communication between your application and a JMS-compliant message broker. The following figure shows an overview of how the communication works:

Gateway

Pre-requiste

There are two key pre-requiste to build our .NET solutions for Kaazing websocket

  • Make sure that your computer has the latest Windows service pack and critical updates.
  • Assembly com.kaazing.gateway.jms.client.dotnet

Server Side

Complete set of server side code is listed below. Let us see the details of source code in the following sections.

using Kaazing.JMS;
using Kaazing.JMS.Stomp;
using System.Threading;

namespace JMSPubSubDemo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private IConnection connection = null;
        private IDictionary<string,>> consumers = null;
        private ISession session = null;
        public MainWindow()
        {
            InitializeComponent();

            #region Establish the connection
            IConnectionFactory conFactory = new StompConnectionFactory(new Uri("ws://localhost:8001/jms"));
                try
                {
                    
                    connection = conFactory.CreateConnection("test", "test");
                    consumers = new Dictionary<string,>>();
                    session = connection.CreateSession(false, SessionConstants.AUTO_ACKNOWLEDGE);

                    connection.Start();
                    SubscriberWindow sub = new SubscriberWindow();
                    sub.Show();
                }
                catch
                {

                }
            #endregion Establish the connection
        }
    }

    public class MessageHandler : IMessageListener
    {
        Page page;
        internal MessageHandler(Page page)
        {
            this.page = page;
        }

        public void OnMessage(IMessage message)
        {
            page.Dispatcher.BeginInvoke(() =>
            {
                if (message is ITextMessage)
                {
                    ITextMessage textMessage = (ITextMessage)message;
                }
                else if (message is IBytesMessage)
                {
                    IBytesMessage msg = (IBytesMessage)message;
                    byte[] actual = new byte[(int)msg.BodyLength];
                    msg.ReadBytes(actual);
                }
            });
        }
    }
}
		</string,></string,>

Connection Creation

To start with, you need to add an IConnectionFactory, which is a WebSocket gateway .NET JMS client API that captures the URL for the connection. Using the connection factory, you need to create a connection to the location you want to use as below:

IConnectionFactory conFactory = new StompConnectionFactory(new Uri("ws://localhost:8001/jms"));
connection = conFactory.CreateConnection("test", "test");		
		

Session Creation

After you create a connection, you must create a session as:

consumers = new Dictionary<string,>>();
session = connection.CreateSession(false, SessionConstants.AUTO_ACKNOWLEDGE);
		</string,>

Connection Start

Once the IMessageConsumer is created, start the message flow by starting the connection:

connection.Start();
		

Client Side

At the client side SubscriberWindow.xaml, you need to write the listener by adding the IMessageListener that implements ITextMessageHandler as:

public partial class SubscriberWindow : Window
{
..........
		IDestination destination;
		destination = session.CreateTopic("/topic/myTopic");
		consumer = session.CreateConsumer(destination);
		consumer.MessageListener = new MessageHandler(this);
..........
}
class MessageHandler : IMessageListener 
{ 
    public void OnMessage(IMessage message) 
    { 
        ITextMessage textMessage = (ITextMessage)message; 
        Console.Out.WriteLine("We received this message: "+textMessage.Text); 
    } 
} 

Hotfix for .NET project

To check for the presence of System.Xml.Serialization.dll in C:\Windows\Microsoft.NET\Framework\v4.0.30319. System.Xml.Serialization.dll apparently doesn't (always) get installed with the initial .NET 4 package, but it is included in NDP40-KB2468871-v2-x86.exe . The trick is to download the rollup package and start the installation, which will place System.Xml.Serialization.dll in C:\WINDOWS\Microsoft.NET\assembly\GAC_MSIL\System.Xml.Serialization\v4.0_4.0.0.0__b77a5c561934e089 . From there, one has only to copy the dll to C:\Windows\Microsoft.NET\Framework\v4.0.30319. The installation will fail, of course, before the copy is made, so it is necessary to re-run the installer once more to get to finally go through.

Hotfix NDP40-KB2468871-v2-x86.exe is attached in this article.

WebSocket Advantage

In the world of web browsing, the less time it takes to load a page, the better. The importance of load time is evident by the fact that it is measured in milliseconds. Speed is king in the land of web browser.For every 100 milliseconds that were shaved off of Amazon.com’s load time, a 1% increase in revenue was achieved.

With such evidence cited, it’s clear that web site performance is not just a luxury anymore.

  • Web Sockets can offer such an incredibly dramatic reduction of unnecessary network traffic and latency by comparing it to conventional solutions.
  • Proven technology in Google. So, Google's Ian Hickson says "educing kilobytes of data to 2 bytes...and reducing latency from 150ms to 50ms is far more than marginal. In fact, these two factors alone are enough to make Web Sockets seriously interesting to Google"

Proof of Concept

People believe if we demonstrate the realization of the proposal with feasible data.

Polling Methodology

Let's take a look at the network throughput for just the HTTP request and response header data associated with this polling application in three different use cases.

    Use case A: 1,000 clients polling every second:
    Network throughput is (871 x 1,000) = 871,000 bytes = 6,968,000 bits per second (6.6 Mbps)
    Use case B: 10,000 clients polling every second:
    Network throughput is (871 x 10,000) = 8,710,000 bytes = 69,680,000 bits per second (66 Mbps)
    Use case C: 100,000 clients polling every 1 second:
    Network throughput is (871 x 100,000) = 87,100,000 bytes = 696,800,000 bits per second (665 Mbps)
        

That's an enormous amount of unnecessary network throughput.

WebSocket Methodology

If only we could just get the essential data over the wire. Well, guess what? Each of these messages is a WebSocket frame that has just two bytes of overhead (instead of 871). Take a look at how that affects the network throughput overhead in our three use cases.

    Use case A: 1,000 clients receive 1 message per second:
    Network throughput is (2 x 1,000) = 2,000 bytes = 16,000 bits per second (0.015 Mbps)
    Use case B: 10,000 clients receive 1 message per second:
    Network throughput is (2 x 10,000) = 20,000 bytes = 160,000 bits per second (0.153 Mbps)
    Use case C: 100,000 clients receive 1 message per second:
    Network throughput is (2 x 100,000) = 200,000 bytes = 1,600,000 bits per second (1.526 Mbps)
        

Comparision Result

As seen, Web Sockets provide a dramatic reduction of unnecessary network traffic compared to the polling solution. PoC Result

Points of Interest

Hope, it will be interesting to have detailed study about the core concepts of the emerging WebSocket technology.

History

  • Version 1.0 - Initial Version.

License

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

About the Author

GanesanSenthilvel
Architect
India India
Member
Currently working as IT Solution Architect for Financial Services applications. Out of 18+ years, spent six career years at major IT firms in USA. Basically from C, C++, VC++, C# family, extending to the emerging Big Data and Cloud technology. Loves driving, spending time with friends&family, building my farm house.

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   
Questionhjmemberlminhtm5 Nov '12 - 18:15 
AnswerRe: hjmemberGanesanSenthilvel14 Nov '12 - 1:53 
GeneralMy vote of 5memberLakxman14 Oct '12 - 21:51 
GeneralRe: My vote of 5memberGanesanSenthilvel18 Oct '12 - 5:21 
GeneralMy vote of 5memberPrabhakaran Soundarapandian10 Aug '12 - 3:22 
GeneralRe: My vote of 5memberGanesanSenthilvel10 Aug '12 - 6:07 
GeneralMy vote of 5memberKim Togo9 Aug '12 - 7:19 
GeneralRe: My vote of 5memberGanesanSenthilvel9 Aug '12 - 7:25 
GeneralMy vote of 5memberAmbalavanar Thirugnanam9 Aug '12 - 6:19 
GeneralRe: My vote of 5memberGanesanSenthilvel9 Aug '12 - 6:24 
QuestionVote of 5memberNewCoder20129 Aug '12 - 2:15 
AnswerRe: Vote of 5memberGanesanSenthilvel9 Aug '12 - 6:24 

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.130516.1 | Last Updated 9 Aug 2012
Article Copyright 2012 by GanesanSenthilvel
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid