WebSocket avec ASP.NET 4.5 et Microsoft.Websockets

Websocket est un standard qui permet de « développer un canal de communication bidirectionnel et full-duplex sur un socket TCP pour les navigateurs et les serveurs web. » C’est que l’on fait actuellement lorsque l’on utilise des XMLHttpRequest avec Ajax. En dotnet SignalR permettait déjà de profiter de ces features, maintenant il est possible de le faire en dotnet avec ASP.NET 4.5 à certaines conditions :

–          Application sur un IIS 8 avec la feature WebSockets

–          .NET 4.5

–          Un client compatible (IE10, Chrome 13+, Safari 5+, Opera 5+)

Premièrement, assurez-vous que le WebSocket est activé sur IIS.  Ensuite, créez un projet ASP.net et ajoutez le package NuGet Microsoft.Websockets. C’est la manière la plus simple d’obtenir l’assembly vu le DLL Hell de Microsoft.Websockets. Ajoutez aussi le package JQuery (1.8.2 dans ce cas-ci), il nous fournit une API JavaScript nous permettant de consommer des WebSockets.

Pour le reste il nous faut 3 fichiers ici. Un index.html qui contiendra le formulaire de chat ainsi que le code javascript pour l’établissement de la connexion et l’envoi/reception des données avec le websocket, un HTTPhandler qui fournira le websocket au httpcontext et notre implémentation du websocket basé sur Microsoft.Web.WebSockets.WebSocketHandler qui se base sur l’API Websocket du W3C. Pour le reste, je vous laisse lire les commentaires détaillés du code. La solution est également disponible via mon skydrive.

index.html

<!doctype html>
    <head>
        <script src="Scripts/jquery-1.8.2.min.js" type="text/javascript"></script>
        <script type="text/javascript">
            
            $(document).ready(function () {
                // Obtention du pseudo
                var name = prompt('Pseudo :');
                
                // Url du websocket, pour de l'https utiliser wss://
                var url = 'ws://' + window.location.hostname + window.location.pathname.replace('index.htm', 'socket.ashx') + '?name=' + name;
                
                //Affichage de l'url de connection et création websocket
                alert('Connecting to: ' + url);
                
                ws = new WebSocket(url);
        
                // On Websocket open, notification utilisateur
                ws.onopen = function () {
                    $('#messages').prepend('Connected <br/>');
                    // On Click on Send, envoi du contenu de txtMessage
                    $('#cmdSend').click(function () {
                        ws.send($('#txtMessage').val());
                        $('#txtMessage').val('');
                    });
                };
        
                // On Receive message on websocket, Ajouter le message à la chat box
                ws.onmessage = function (e) {
                    $('#chatMessages').prepend(e.data + '<br/>');
                };

                // On Click on Leave Button, fermer le websocket
                $('#cmdLeave').click(function () {
                    ws.close();
                });

                // On Close websocket, notification utilisateur
                ws.onclose = function () { $('#chatMessages').prepend('Closed <br/>'); };

                // On Error on the websocket, notification utilisateur
                ws.onerror = function (e) { $('#chatMessages').prepend('Oops something went wront <br/>'); };

            });

        </script>
    </head>
    <body>
        <input id="txtMessage" />
        <input id="cmdSend" type="button" value="Send" />
        <input id="cmdLeave" type="button" value="Leave" />
        <br />
        <div id="chatMessages" />
    </body>
</html>

TestWebSocketHandler.cs

using Microsoft.Web.WebSockets;

namespace Istace.Blog.WebSockets
{
    /// <summary>
    /// WebSocket Handler
    /// </summary>
    /// <remarks>
    /// Implémentation de la W3C WebSocket API
    /// http://www.w3.org/TR/2009/WD-websockets-20091222/
    /// </remarks>
    public class TestWebSocketHandler : WebSocketHandler
    {
        /// <summary>
        /// List of the connected connectedClients.
        /// </summary>
        private static readonly WebSocketCollection ConnectedClients = new WebSocketCollection();

        /// <summary>
        /// Socket Name
        /// </summary>
        private string _name;

        /// <summary>
        /// Occurs when WebSocket open.
        /// </summary>
        public override void OnOpen()
        {
            // Get the name
            _name = WebSocketContext.QueryString["name"];
            // Add client to the client list
            ConnectedClients.Add(this);
            // Broadcast to connected connectedClients the connection message
            ConnectedClients.Broadcast(_name + " has connected.");
        }

        /// <summary>
        /// Occurs when WebSocket receieve message
        /// </summary>
        /// <param name="message"></param>
        public override void OnMessage(string message)
        {
            // broadcast the message to the registred connectedClients
            ConnectedClients.Broadcast(string.Format("{0} said: {1}", _name, message));
        }

        /// <summary>
        /// Occurs when the WebSocket close
        /// </summary>
        public override void OnClose()
        {
            // Remove the instance from the connected client list.
            ConnectedClients.Remove(this);
            // Broadcast the deconnection message to the registred clients.
            ConnectedClients.Broadcast(string.Format("{0} has gone away.", _name));
        }
    }
}

socket.ashx

using System.Web;
using Microsoft.Web.WebSockets;

namespace Istace.Blog.WebSockets
{
    /// <summary>
    /// WebSocket HTTP Handler
    /// </summary>
    public class WSHttpHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            if (context.IsWebSocketRequest)
                context.AcceptWebSocketRequest(new TestWebSocketHandler());
        }

        public bool IsReusable { get { return false; } }
    }
}

Websockets with ASP.net 4.5 and Visual Studio 2012
WebSocket on MSDN
W3C WebSocket API Reference

Published by Emmanuel Istace

Musician, Software developer and guitar instructor. https://emmanuelistace.be/

4 thoughts on “WebSocket avec ASP.NET 4.5 et Microsoft.Websockets

  1. . Celui‐ci reprend l’essentiel de SPDY en essayant de tenir compte des appareils nomades, et en particulier d’optimiser les accès réseau pour accroître la durée de vie des batteries. Un rôle plus important est accordé aux websockets, mais pour l’essentiel l’approche est relativement similaire à celle de Google.

  2. there was websocket ooerror in client side ‘ undefined ‘ error and i can’t solve this problem

    Please help

  3. Some options for trying to drunk driving defense run thhe risk of higher sentence.
    In thee state administered shouldn’t have been booked
    under DUI case cann have a couple oof drinks at dinner.
    A DUI lawyer to represeent you and your reputation by going to jail.

    A DUI Attorney can also be loked into. When you are
    going to hand out more penalties for a good DUI attorney will argue whether the
    city of Los Angeles DUI lawyer can challenge the accuracy of
    any kind of impaired driving.

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 )

Connecting to %s

%d bloggers like this: