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

22 thoughts on “HTML5-Developing WebSocket Server using C# .NET

  1. Great post! That really helped me understand how to get a WebSockets server up and running in the .NET environment.

  2. I am having problems getting the Alchemy WebSockets server working properly. Where can I get help? I am building a WebForms application that uses the Alchemy WebSockets server. Will that work? I am getting strange results where my application runs for about a minute and then it just shuts down. I don’t get any error messages. It just shuts down. It sends updates to the web page ok for about one minute, then the application just stops working and shuts down. Any ideas?

  3. There’s an issue with your code.
    After a “Connection Established confirmation” there a few ‘Data Sent’ by the server.
    After 4 calls, there’s a message which says
    “Client Disconnected: ” + Ip of the client

    At this point, Visual Studio presents a “NullReferenceException was unhelded” error.

    Any guesses? The project looks great but this kinda blocks any potential use.

  4. Really interesting! I had to change Target Framework from .NET 4 Framework Client Profile (default on creating a new project) to .NET 4 Framework. A few doubts:

    – This server multi-threaded right? How many connections can it handle safely?
    – Didn’t worked on Internet Explorer (I have version 9) and I allowed scripts/ActiveX to run after opening the page. Any ideas what do I have to change on client.html to make it work on IE?

  5. Not working.
    Cant build the server because the VS cant resolve the name Alchemy. Yes, put a reference to the Alchemy.dll

    • Try changing the target framework from “.NET 4 Framework Client Profile” (default on creating a new project) to “.NET 4 Framework.” on the project properties. If I’m not mistaken after I changed this, it worked for me.

      • Good question, but I have no idea, hehe. Haven’t looked up. Anybody can explain or already googled that?

  6. This example is working fine and now I want to use in real world.
    Imagine that u have access to Datas.asp page, where u can watch all database (A and B) manipulations (make through other pages) in real time. Your example works fine, but, if another user can access the same Datas.asp and should only see changes in certain database (A). My question is, how can I choose witch user will receive the updates that other users make?

    • In the example I used the Alchemy.Classes.UserContext.ClientAddress, the remote endpoint address as the key to store all online connections, you can customize the client to send user preferences from the session to the web socket server and maintain the lists of connections based on the update preference as the key. And server can obtain list of connections for the corresponding updates based on the update preference key, when it needs to send an update message.

  7. Pingback: Websockets | Florian Verdonck | Portfolio

  8. I have modified the code according what you say in order to make it work through the internet:

    conn = new WebSocket(‘ws://2.138.15.213:8100’);

    Port 8100 is open, but any client is able to connect!. Locally is working perfect.

    Any ideas about what is my problem???

    By the way, nice article!

  9. This is a very great post !
    Very simple, fast, comprehensible !
    Thank you very much for you and OLIVINE LABS !
    Its a powerfull technology.

  10. Once i run the program.cs and connect the code i am immediately getting the output has disconnected from: there is no connection message appearing any help?

    Thanks in advance

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s