HTML5-Developing WebSocket Server using C# .NET

WebSocket provides the bi-directional communication, which allows data to be sent back and forth at the same time, without requiring to request from server or client. So once the WebSocket connection is established, data can be pushed across without either side having to ask for it.

Following is the best references to get started with understanding all about websockets and its benefits.

All about HTML5 WebSocket
http://www.websocket.org/aboutwebsocket.html

Benefits of WebSocket (Reduce unnecessary network overhead and latency)
http://www.websocket.org/quantum.html

There are many WebSocket libraries available to support the development of WebSocket server in C# .net, but the most efficient, and one of the easiest to use is the Alchemy Websockets (http://alchemywebsockets.net/)

The current version (2.2.1.238) supports the latest Google chrome, Mozilla Firefox, Safari on mac/windows and mobile devices (iPhone/iPad).

To begin with the development of WebSocket Server, goto the github repository at https://github.com/Olivine-Labs/Alchemy-Websockets and download the source code.

Open “Alchemy.sln” solution with Visual Studio.

Change Solution Configuration from “Debug” to “Release” mode and build the “Alchemy” project.

Create a new Visual C# Console Application project and name it “AlchemyWebSocketServer”. Go to “References” -> Add Reference -> Browse and add reference to “Alchemy.dll” file.

update the “Program.cs” with this code – https://gist.github.com/2976928.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Alchemy;
using Alchemy.Classes;
using System.Collections.Concurrent;
using System.Threading;


namespace AlchemyWebSocketServer
{
    class Program
    {
        //Thread-safe collection of Online Connections.
        protected static ConcurrentDictionary OnlineConnections = new ConcurrentDictionary();
        
        static void Main(string[] args)
        {
            // instantiate a new server - acceptable port and IP range,
            // and set up your methods.

            var  aServer = new WebSocketServer(8100,System.Net.IPAddress.Any)
            {
                                  OnReceive = OnReceive,
                                  OnSend = OnSend,
                                  OnConnected = OnConnect,
                                  OnDisconnect = OnDisconnect,
                                  TimeOut = new TimeSpan(0, 5, 0)
            };
            aServer.Start();


            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.Title = "Alchemy WebSocket Server";
            Console.WriteLine("Running Alchemy WebSocket Server ...");
            Console.WriteLine("[Type \"exit\" and hit enter to stop the server]"); 


            // Accept commands on the console and keep it alive
            var command = string.Empty;
            while (command != "exit")
            {
                command = Console.ReadLine();
            }

            aServer.Stop();

        }

        public static void OnConnect(UserContext aContext)
        {
            
            Console.WriteLine("Client Connected From : " + aContext.ClientAddress.ToString());
            
            // Create a new Connection Object to save client context information
            var conn= new Connection {Context=aContext};

            // Add a connection Object to thread-safe collection
            OnlineConnections.TryAdd(aContext.ClientAddress.ToString(), conn);
            
        }

       

        public static void OnReceive(UserContext aContext)
        {
            try
            {
                Console.WriteLine("Data Received From [" + aContext.ClientAddress.ToString() + "] - " + aContext.DataFrame.ToString());

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
            }
            
        }
        public static void OnSend(UserContext aContext)
        {            
            Console.WriteLine("Data Sent To : " + aContext.ClientAddress.ToString());
        }
        public static void OnDisconnect(UserContext aContext)
        {
            Console.WriteLine("Client Disconnected : " + aContext.ClientAddress.ToString());

            // Remove the connection Object from the thread-safe collection
            Connection conn;
            OnlineConnections.TryRemove(aContext.ClientAddress.ToString(),out conn);

            // Dispose timer to stop sending messages to the client.
            conn.timer.Dispose();
        }
    }

    public class Connection
    {
        public System.Threading.Timer timer;
        public UserContext Context { get; set; }
        public Connection() {
            this.timer = new System.Threading.Timer(this.TimerCallback, null, 0, 1000);
        }

        private void TimerCallback(object state)
        {
            try
            {
                // Sending Data to the Client
                Context.Send("[" + Context.ClientAddress.ToString() + "] " + System.DateTime.Now.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }
    }
}

Build and run the "AlchemyWebSocketServer".

Here we are ready for testing the websocket server with html5 websocket client.

Create a “client.html” file with this code – https://gist.github.com/a9409a82d2379d52e9af  and publish it on your webserver.

Note: If websocket server and webserver are running on the different machines, make sure to change the websocket server address (‘ws://localhost:8100’) with correct IP address or hostname.

Now lets see how it works. Open up browser and navigate to the URL where you have published “client.html”.
Its working fine for me on Google Chrome (19.0.1084.56 m), Mozilla Firefox (13.0), Safari (5.1.7 – 7534.57.2), Safari on iPhone/iPad (iOS 5.1.1-9B206)

Console Messages

Isn’t that so simple to implement websocket with your favorite language C# .NET.
Thanks to OLIVINE LABS (http://olivinelabs.com/) for making this library available under MIT and LGPL licenses.

Advertisements