Het internetverkeer wordt per definitie geïnitieerd vanuit de client. Deze doet een verzoek (request) richting de server. De server zal vervolgens een antwoord (response) geven bijvoorbeeld in de vorm van een HTML pagina. Maar wat als we een bericht willen sturen vanaf de server naar de client? Heel lang zijn daar alleen workarounds voor geweest, maar met de komst van Websockets is dit wel mogelijk.

Polling

De request-response structuur is de basis van het HTTP verkeer. De client doet een verzoek (blauwe lijn) via het internet naar de server. De server behandelt het verzoek en stuurt een antwoord. Vaak een HTML pagina, maar data is bijvoorbeeld ook mogelijk in het geval van een (web)service.
 

Soms wil je juist vanaf de server een bericht naar de client sturen. Denk bijvoorbeeld aan live voetbal standen. Je wilt niet continu op F5 hoeven drukken om te zien of er nog gescoord is. Of een veiling, dan wil je graag weten wanneer er een ander bod geplaatst is.
 
Request-response werkt in dit soort situaties niet optimaal. Mogelijke oplossing waren tot voorkort:
 
Polling: Een JavaScript functie op de client doet met grote regelmaat een request naar de server om te vragen of er nog nieuws is. Het grote nadeel is dat een groot deel van de requests zinloos zullen zijn, want vaak zal het scorebord niet veranderen tijdens de wedstrijd. Tevens is het niet real-time, want er zit altijd wat tijd tussen de verschillende requests.
 
Long Polling: De client doet een request naar de server, maar deze geeft pas een response terug wanneer er daadwerkelijk nieuws is. Dit scheelt resources, maar je loopt ook tegen zaken aan als time-outs en dergelijke.

 

HTML 5 Websockets

Binnen het hele scala aan functionaliteiten die onder de HTML 5 noemer beschikbaar zijn gekomen, valt ook Websockets. Met Websocket zet je een verbinding op tussen de client en de server. De client kan berichten naar de server sturen, maar de server kan ook berichten richting client sturen. Sterker nog, er kunnen meerdere clients koppelen met dezelfde server en op die manier kan een bericht van de server naar meerdere clients verstuurd worden.
 

SignalR

Om je op weg te helpen zijn er libraries beschikbaar die je helpen om websockets op te zetten. Voor .Net developers is er bijvoorbeeld SignalR.
Deze library bevat zowel de server als de client implementaties (C# en JavaScript). Tevens zorgt de library voor backward compatibility; mocht iemand nog gebruik maken van een oude browser of server, dan zal er over geschakeld worden op long polling. SignalR is eenvoudig te installeren via een NuGet package of het downloaden via de website: http://signalr.net
 
Op de server is het een kwestie van een "Startup” class toe voegen (na het toevoegen van de NuGet package aan je project)

  public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
        }
   }


En een class die de berichten ontvangt en verstuurd:

   public class MessageHub : Hub
    {
        public void Send(string message)
        {
            // Call the broadcastMessage method to update clients.
            Clients.All.broadcastMessage(message);
        }
   }
Dat is alles!
Voor de client maak je bijvoorbeeld een HTML pagina. (Clients mogen ook windows applicaties, of telefoon apps zijn, maar hier gebruik ik de JavaScript implementatie).
Uiteraard moeten er referenties worden gelegd naar de scripts die de NuGet Package heeft toegevoegd. En naar de automatisch gegenereerd "signalr/hubs”.

    <!--Reference the jQuery library. -->
    <script src="Scripts/jquery-1.6.4.min.js"></script>
    <!--Reference the SignalR library. -->
    <script src="Scripts/jquery.signalR-2.2.3.min.js"></script>
    <!--Reference the autogenerated SignalR hub script. -->
    <script src="signalr/hubs"></script>

Vervolgens kan de connectie worden gelegd naar de server. Let op: de Class op de server heb ik "MessageHub” genoemd. Automatisch genereert SignalR daarom een JavaScript object "$.connection.messageHub”. Mocht je je C# Class anders noemen, dan zul je uiteraard ook het javascript object anders moeten noemen.

 
        $(function () {
            // Declare a proxy to reference the hub.
            var hub = $.connection.messageHub;
            // Create a function that the hub can call to broadcast messages.
            hub.client.broadcastMessage = function (message) {
                // Message received
            };     
 
            // Start the connection.
            $.connection.hub.start().done(function () {
               // set eventhandlers if needed, call the send function from the handler
               // hub.server.send("message")
            });
        });


Voorbeeld

De performance (het aantal berichten per seconde) is erg goed en het inzet gebied is mede daardoor heel breed. Denk bijvoorbeeld maar eens aan de wereld van IoT, waarbij slimme devices continue in contact staan met servers en berichten met elkaar uitwisselen. Of een Remote Desktop connection, maar dan zonder plugins. De server stuurt continue scherm updates naar de client. De mogelijkheden zijn eindeloos.

Tijd om websockets in actie te zien! Hieronder zie je een gekleurd vlak. Wanneer je erop klikt verschijnt er een colorpicker. Wanneer je een andere kleur uit kiest, veranderd niet alleen de kleur van het vlak op jouw scherm, maar ook bij andere gebruikers die deze pagina open hebben. Probeer het maar eens door de pagina op 2 verschillende browsers te openen. Of nog duidelijker, op 2 apparaten (bijvoorbeeld je telefoon)

Je ziet op beide scherm realtime de kleur aangepast worden. Berichten met de gewenste kleur wordt van de client naar de server gestuurd en vervolgens stuurt de server het naar alle clients die ook verbonden zijn.

Training

Meer weten over HTML 5 en Websockets? Kijk dan eens naar deze training:

Training Programming in HTML5 with JavaScript and CSS3