16. Web Sockets

About this Tutorial

Objectives

Delegates will learn to develop applications using HTML5/CSS3 and JS. After completing this course, delegates will be able to:

  • Use Visual Studio 2012 effectively
  • Create commercial HTML5 Web Applications
  • Develop Websites that may use web sockets, animations and geolocation

Audience

This course has been designed primarily for programmers new to the .Net development platform. Delegates experience solely in Windows application development or earlier versions of HTML/CSS and JavaScript will also find the content beneficial.

Prerequisites

No previous experience in web programming is required. But any experience you do have in programming will help. Also no experience in browser IDE’s is required. But again any experience you do have with programming development environments will be a valuable.

Download Solutions

HTML tutorial


Overview

Estimated Time – 1 Hour

Not what you are looking? Try the next tutorial – Web Workers

  1. Traditional HTTP Communication
    • Traditionally, 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
    • In some cases, the response could be stale by the time the browser renders the page
      • E.g. stock prices, news reports, ticket sales, etc.
    • How can you ensure you get up-to-date information?
      • Polling
      • Long polling
  2. Polling
    • This is how polling works in traditional HTTP:
      • The browser sends HTTP Ajax requests at regular intervals, and immediately receives a response
    • Issues:
      • Real-time data is often not that predictable, so the browser will probably make unnecessary requests
      • Connections will probably be opened and closed needlessly in low-message-rate situations
      • HTTP is a very verbose protocol for such fine-grained communication!
  3. Long Polling
    • This is how long polling works in traditional HTTP:
      • The browser sends a request to the server and the server keeps the request open for a set period of time
      • If the server has some useful data to return within that period, it sends a response containing the data
      • Otherwise, it sends a response to terminate the open request
    • Issues:
      • In high message-volume, long-polling doesn’t provide any substantial performance improvements over traditional polling
      • The server might only support a certain number of concurrent HTTP connections
  4. The Problem with These Approaches:
    • HTTP was simply not designed for real-time full-duplex communication
      • All of the methods described involve lots of HTTP request/response headers (=> high latency)
    • Furthermore, in an attempt to simulate full-duplex communication over half-duplex HTTP:
      • The traditional approaches have typically used two separate connections (one for upstream, one for downstream)
      • Maintaining and coordinating these two connections consumes extra resources and adds complexity
  5. HTML5 Web Sockets to the Rescue
    • Web Sockets is the most powerful communication feature in the HTML5 specification
    • Web Sockets defines a full-duplex communication channel between browser and server
      • Simultaneous 2-way data exchange between browser and server
      • A large advance in HTTP capabilities
      • Extremely useful for real-time, event-driven Web applications

Lab 1: Understanding HTML5 Web Sockets

Lab 1: Understanding HTML5 Web Sockets
  1. The Web Sockets Upgrade Handshake
    • To support real-time full-duplex communication between a client and server:
      • The client and server upgrade from the HTTP protocol to the Web Sockets protocol during their initial handshake
        • The client sends an HTTP request containing an “upgrade to Web Sockets” HTTP header
        • The server (hopefully) returns an HTTP response containing an “OK to upgrade to Web Sockets” HTTP header
      • Thereafter, client and the server can communicate in full-duplex mode over the open connection
        • Allows the server to push information to the client, when the data becomes available
        • Allows the client and server to communicate simultaneously
  2. The WebSocket Interface
    • Along with the definition of the Web Sockets protocol, the specification also defines the WebSocket interface
      • For use in JavaScript applications
        interface WebSocket {
         readonly attribute DOMString URL;
         // ready state
         const unsigned short CONNECTING = 0;
         const unsigned short OPEN = 1;
         const unsigned short CLOSED = 2;
         readonly attribute unsigned short readyState;
         readonly attribute unsigned long bufferedAmount;
         // networking
         attribute Function onopen;
         attribute Function onmessage;
         attribute Function onclose;
         attribute Function onerror;
         boolean send(in DOMString data);
         void close();
        };
  3. The Beneficial Effect of Web Sockets
    • HTML5 Web Sockets provide a dramatic reduction of unnecessary network traffic compared to polling
      • ~ 500:1 reduction in unnecessary HTTP header traffic
      • ~ 3:1 reduction in latency
    • These are huge improvements!
      • A major step forward in the scalability of real-time Web apps
  4. Web Sockets Servers
    • Node.js
      • https://nodejs.org
    • Microsoft
      • Internet Information Services 8
    • PHP
      • https://code.google.com/p/phpwebsocket/
    • Apache HTTP Server extension
      • https://code.google.com/p/pywebsocket/
    • Java
      • https://jwebsocket.org/
    • Ruby
      • https://github.com/gimite/web-socket-ruby
Lab
  1. In this lab, you’ll implement a Chat Room web application by using HTML5 Web Sockets. The application will incorporate server code and client code, as follows:
    • The server code will be implemented in C# and .NET, and will allow multiple clients to “enter” the chat room. This code will run on the Microsoft Internet Information Services (IIS) version 8, which supports the Web Sockets protocol.
    • The client code will be a Web page, implemented in HTML5 and JavaScript. The Web page will run in any browser that supports Web sockets, such as Internet Explorer 10, Chrome, or Safari. The Web page will allow a user to connect to the server and send and receive messages over a Web Sockets connection.
  2. When the client sends a message to the server, the server will receive the message and broadcast it back to all clients (you can have multiple browser windows, representing different clients). Each client will display a transcript of all the messages broadcast from the server, from every user.
  3. We’ll provide all the server code, and you’ll implement the client code
  4. You can download the solutions at the top of the tutorial; inside will be two documents containing code for you to use in the tutorial. These will be in folders labelled initial and final, the initial folder is what you will be using with all the finished code in the final folder.
  5. Creating the project
    • When you want to implement a Web Sockets solution, your first task is to choose a Web server platform that supports Web Sockets. We’ll be using Microsoft IIS 8 in this lab.
    • You must also decide what technology to use to implement the server code. In recent times, a common approach has been to implement an ASP.NET HTTP handler (a .NET class with an .ashx file extension). An alternative (and simpler) approach since the advent of ASP.NET 4.5 is to create an ASP.NET MVC 4 project. MVC4 includes new APIs that support Web Sockets directly, so it will be a popular approach in the future.
    • So we’re going to create an ASP.NET MVC 4 project, which will house server code to handle Web Sockets messages from clients. We’ll use Visual Studio to create the project, and to deploy it to IIS when we’re ready. In order for the deployment to succeed, you must start Visual Studio as an Administrator as follows:
      • Right-click the Visual Studio 2012/13 start-up icon.
      • In the popup menu, click Run as administrator.
      • In the User Access Control message box, click Yes.
    • In Visual Studio 2012/13, create a new MVC4 Web project as follows:
      • Click File | New | Project.
      • In the New Project dialog box:
        • Locate the Search text box in the top-right corner, and type-in MVC. The main section of the dialog box should display various templates, select the ASP.NET MVC 4 Web Application template (in Visual C#).
        • In the Name text box at the bottom of the dialog box, type-in Chat.
        • In the Location text box, specify the location of the root folder.
        • The click OK.
      • Another dialog box appears, asking which project template to use:
        • Select the Web API template (Web API is a new project template in ASP.NET MVC 4, which makes it easy to implement RESTful Web services ;it’s also ideal for implementing Web Sockets end points).
        • In the View Engine drop-down list, ensure the Razor option is selected. A View Engine is something MVC uses to process code in server-side Web pages (these pages contain a mixture of static HTML and dynamic content generated at the server e.g. a table of data from a database query). Razor is the View Engine of choice these days!
        • Deselect the option for creating a unit-test project.
        • Click OK.

Lab 2: Defining a Web Sockets server

Lab 2: Defining a Web Sockets server
  1. Overview
    • In this section we’re going to see how to implement a Web Sockets server
      • We’ll implement the server in Node.js
      • Node.js is a JavaScript library for building server-side applications
    • The demo code is located in the NodeJsSockets folder
      • Server file: socketserverWS.js (discussed in this Section)
      • View code file.
      • Client page: socketclient.html (discussed in next Section)
      • View code file.
    • To install Node.js on your computer:
      • Run node-v0.8.19-x64.msi
      • Installs in the Program Files folder, in the nodejs sub-folder
  2. Support for Web Sockets in Node.js
    • Node.js is just a JavaScript engine
      • It’s not a native “web server” or a “web sockets server
      • You have to write code to support HTTP and WS requests
    • If you want to support Web Sockets in Node.js, you must download the Web Sockets module (i.e. object)
      • Run this command from a Command Window (as Administrator):
        npm install websocket@1.0.3
    • This creates a sub-folder named node_modules
      • Contains the Node.js Web Sockets module
      • Plus any other Node.js modules you might choose to install.
  3. Implementing Web Sockets in Node.js
    • To run the sample Web Sockets server:
      • Run the following command from a Command Prompt Window:
      • View code file.
      • node socketserverWS.js

    • The following summarizes socketserverWS.js
      • See the code in socketserverWS.js for full implementation details and narrative comments
      • View code file.
      • Feel free to skip these details if you don’t need to know how the Node.js server works!
  4. Creating HTTP and Web Sockets Servers
    • We first create an HTTP server
      • We implement an HTTP server that listens on port 8888
      • When it receives a “/” HTTP request, it returns index.html
    • We then create a Web Sockets server that “piggy-backs” on the HTTP server
      • We set the autoAcceptConnections property to false
      • Allows us to check the origin of all client requests, to decide whether we want to accept the connection request from the client
  5. Handling Client Interactions
    • We handle connection requests from clients
      • Each client request is a request event
      • We check the request.origin property, which identifies the origin of the client that’s requesting the connection
      • If the request.origin is satisfactory, we accept the request and add the client’s connection to an array
    • We handle messages sent from clients
      • Each client request is a message event
      • If it’s a text message, we echo the message back to client
      • If it’s a binary message, we echo the message size back to client
    • We handle disconnections
      • When a client closes the connection, we remove the connection from the our array
  6. Sending Messages to Clients
    • Every 1 second, we send a message to each client
      • The message simply tells each client how many clients are currently connected
      • This illustrates the ability to implement full-duplex asynchronous communication between clients and servers using Web Sockets
Lab
  1. Implementing the server
    • You now have an MVC Web API project. This project will actually house everything for the Chat Room application, including server-side code and client-side web pages.
    • You’ll implement the server-side code first. The good news is that MVC 4 introduces new classes that support Web Sockets directly. The bad news is that these classes aren’t pre-installed in the .NET Framework, you have to download them into your project. You use the NuGet Package Manager to do this:
      • In Visual Studio, in the Solution Explorer window, right-click the Chat project and click Manage NuGet Packages.
      • In the ensuing dialog box, in the left-hand side of the window, click Online. Then in the top-right corner, in the Search text box, type-in WebSockets.
      • The main section of the dialog box should show a bunch of packages that you can download and install. Locate the Microsoft.WebSockets option, and click Install.
      • The installation only takes a few seconds, a green tick will appear when it’s complete. At this time, you can close the dialog box.
    • Now you’re ready to implement the Web Sockets server code. To implement a Web Sockets server (whatever technology you’re using), you must write some code that intercepts an HTTP request from a client that wants to establish a Web Sockets conversation with the server. You must then return an HTTP response that says yes, that’s fine, I understand Web Sockets, so we can have a Web Sockets conversation from now on.
    • This might sound quite tricky, but actually it’s very easy, Here’s what you need to do:
      • In Solution Explorer, expand the Controllers folder. This folder contains two files:
        • HomeController.cs – This is a traditional MVC controller class, which handles normal HTTP requests for Web pages. We’ll discuss this in more detail in the next part of the lab, when we describe how to implement the client Web page.
        • View code file.
        • ValuesController.cs – This is a Web API MVC controller class, to handle RESTful requests from clients. Rename this file to ChatController.cs (this should also rename the class to ChatController).
        • View code file.
      • Open ChatController.cs. The ChatController class has a series of methods that handle HTTP requests from the client, to GET, POST, PUT, or DELETE data at the server. Delete all this code, and paste-in the code from the Snippet1: Server Code.txt file in the initial folder. There is quite a lot of code here, but the comments explain how it all works.
  2. Implementing the client
    • You’re now ready to implement the client. This will be a Web page that contains a mixture of HTML and JavaScript, to establish a Web Sockets connection with the server and to have an on-going Web Sockets conversation with the server.
    • Follow these steps to get started:
      • In the Controllers folder, open HomeController.cs. The class has a single method named Index(). This is known as an action method, and it will map to the default URL for your Web application. In other words, when the user opens a browser window and enters a URL such as https://localhost/Chat, it will send an HTTP request which will be handled by the Index() method.
      • View code file.
      • The Index() method is very simple the statement return View() means find the default view (i.e. Web page) associated with this action method, and return it to the browser. MVC uses a simple naming convention for locating views e.g. if you have a controller named HomeController and an action method named Index(),the default view is /Views/Home/Index.cshtml.
      • View code file.
      • Locate Index.cshtml in Solution Explorer. As it happens, the default implementation of Index.cshtml is pretty hopeless. Delete the entire contents of this file, and paste-in the starter code from the Snippet2 : Client Page.txt file in the initial folder.
      • View code file.
      • Take a look at the new code in Index.cshtml. The file contains a little bit of server-side code (in C#), but it’s mostly client-side HTML/CSS/JavaScript (hence the file extension .cshtml). At the bottom of the file, note the following HTML:
      • View code file.
        • There’s a simple <form> that contains a text box. This is where the user will be able to enter text, ready to send to the server (the form will automatically submit the text when the user presses ENTER).
        • There’s also a <div> named messages. This is where messages will be displayed, when they are broadcast from the server.
      • Now skim to the top of the file and note the following points:
        • We’ve included the Jquery script files, to simplify client-side processing.
        • The init() function contains start-up code. The function initially prompts the user to enter his or her name, and displays the name on the web page. The function then contains a series of TODO comments, asking you to implement the client-side logic for a Web Sockets conversation with the server. You’ll implement all these steps in this exercise…
    • Add code to the init() function, to implement a Web Sockets conversation. Each of the following steps corresponds to a TODO comment in the init() function:
      • Set the uri variable to hold the URL for Web Sockets communication. This will be a URL such as ws://localhost/Chat/api/Chat?username=andy, but rather than hard-coding it like this, build it up bit-by-bit as follows:
        • The URL definitely starts with ws://, because this is how you indicate you want to establish a Web Sockets conversation with the server.
        • The host name might not be localhost, it could be a real domain name such as www.acme.com! How do you know what to use? The simple answer is, the host name of the Web Sockets server is the same as the host name for the current Web page (they come from the same server). You can get the host name of the current web page as follows:
          window.location.hostname
        • You can hard-code the next bit of the URL:
          '/Chat/api/Chat?username='
        • The /Chat part at the beginning is the name of the folder where you’ll be deploying the Web application to IIS. The /api/Chat part indicates that you want the request to be routed to the ChatController class at the server (this is how the Web API works in MVC 4).The ?username= part sets up an HTTP parameter for the request. The parameter will be passed into the action method in ChatController.
        • To finish off the URL, simply append the username variable, this is what should have been made:
          // Ask the user for his/her name, then display it at the top of the page.
          var username = prompt('Please enter a username:');
          $('#chatform').prepend('<h1>Hi ' + username + ', welcome to the chat room!</h1>');
          // Set up the URL of the WebSocket at the server, e.g. ws://localhost/Chat/api/Chat?username=andy
          var uri = 'ws://' + window.location.hostname + '/Chat/api/Chat?username=' + username;
      • Create a new WebSocket object, passing uri as a parameter. Assign the object to the websocket variable. This will set up the Web Sockets connection.
        var websocket = new WebSocket(uri);
      • Handle the “open” event on the websocket object, which signifies a successful connection with the server. In the handler function, do the following:
        • Display a message on the web page, to indicate that we’ve successfully established a Web Sockets connection with the server.
          websocket.onopen = function () {
           $('#messages').prepend('<div class="success">Connected.</div>');
           ...
        • Set up a handler for the submit event on the form. Get the text from the inputbox text box, and send it to the server via websocket.send().
          $('#chatform').submit(function (e) {
               websocket.send($('#inputbox').val());
               $('#inputbox').val('');
               e.preventDefault();
            });
      • Handle the “error” event on the websocket object, which signifies a problem occurred somewhere. Display a simple error message.
        websocket.onerror = function () {
         $('#messages').prepend('<div class="error">An error occurred.</div>');
        };
      • Handle the “message” event on the websocket object, which signifies we’ve received data from the server. Display the message data in the messages element (hint: the event parameter has a data property, which contains the data sent from the server).
        websocket.onmessage = function (e) {
         // Display the message in a special colour if it's actually just our message being bounced back to us.
         if (e.data.match('^' + username)) {
          $('#messages').prepend('<div class="me">' + e.data + '</div>');
         }
         else {
          $('#messages').prepend('<div class="otherPerson">' + e.data + '</div>');
         }
        };

Lab 3: Defining a Web Sockets client

Lab 3: Defining a Web Sockets client
  1. Overview
    • In this section we’ll show how to write a client Web page to call a Web Sockets service
      • The client creates a WebSocket JavaScript object
      • Does your browser support this object?
    • For full client code:
      • See NodeJsSockets/socketclient.html
      • View code file.
      • Copy to localhost and open in Google Chrome (for example)
  2. Checking for Web Sockets Support
    • To check whether your browser supports HTML5 Web Sockets:
      function testWebSocketSupport() {
       if (window.WebSocket) {
        alert("Your browser supports HTML5 Web Sockets");
       }
       else {
        alert("Your browser doesn't support HTML5 Web Sockets");
       }
      }
  3. Opening a Connection
    • Using the WebSocket interface is straightforward.
    • To open a connection to the server:
      • Create a WebSocket object, specifying the URL to connect to
      • Use ws:// prefix for WebSocket connections
      • Use wss:// prefix for secure WebSocket connections
        var url = "ws://localhost:8888/";
        var ws;
        function doInit() {
         ws = new WebSocket(url);
         ...
        }
  4. Handling Events
    • The Web Sockets API is asynchronous
      • You therefore have to handle events as follows:
        var url = "ws://localhost:8888/";
        var ws;
        function doInit() {
         ws = new WebSocket(url);
         ws.onopen  = function(e) { ...};
         ws.onclose  = function(e) { ...};
         ws.onmessage = function(e) { ...};
         ws.onerror  = function(e) { ...};
        }
  5. Sending Data to the Server
    • To send data to the Web Socket server:
      • Call the send() method
      • You can pass text, binary, or array data
        ws.send(sometextdata);
        ws.send(somebinarydata);
        ws.send(somearraydata);
  6. Receiving Data from the Server
    • To receive data messages from the server:
      • Handle the message event
    • The event argument has type and data properties
      • The type property is either “text” or “binary”
      • If “binary”, the WebSocket object has a binaryType property that indicates if it’s a “blob” or an “arrayBuffer”
        function onMessage(e) {
         alert("Received data from server: " + e.data);
         if (e.type == "text") {
          alert("It's text data");
         }
         else {
          if (ws.binaryType == "blob")
           alert("It's a blob [e.g. an image]");
          else if (ws.binaryType == "arrayBuffer")
           alert("It's an array");  
         }
        }
  7. Closing a Connection
    • To close a connection to the server:
      • Call close() on the WebSocket object
      • Optionally pass code and reason parameters
        ws.close();
    • When the connection has been closed, the close event occurs
      • The event object has wasClean, code, and reason properties
  8. Complete Client Example
    • For an example client that interacts with the Node.js Web sockets server:
      • See NodeJsSockets/socketclient.html
      • View code file.
      • Copy to localhost and open in Google Chrome (for example)
        T16P1
Lab
  1. Configuring the system to support Web Sockets
    • IIS 8 supports Web Sockets, but you have to explicitly enable this feature on the computer first. This is a one-off task at the server, and it will probably already be taken care of by the system administrators at your place of work.
    • Follow these steps:
      • Open Control Panel.
      • In Control Panel, click Programs and Features.
      • In the Programs and Features window, click Turn Windows features on or off.
      • In the Windows Features dialog box, enable the following features:
        • Expand the .NET Framework 4.5 Advanced Services node, and enable the ASP.NET 4.5 option.
        • Expand the Internet Information Services node, and enable the Web Management Tools and World Wide Web Services options. Then expand the World Wide Web Services option itself, and enable the ASP.NET 4.5 and WebSocket Protocol options.
    • After you’ve completed these steps, close the Windows Features dialog box, the Programs and Features window, and Control Panel.
  2. Deploying and running the application
    • When you create a normal Web application in Visual Studio, you can run it locally by using Ctrl + F5. Visual Studio kicks off a development server on a pseudo-random port, to act as a cut-down version of IIS.
    • This approach won’t cut it for Web Sockets applications, because the development server doesn’t support Web Sockets. Instead, you need to deploy your application to a fully-fledged IIS 8 Web server (or IIS 8 Express).
    • The following steps describe how to deploy your Web application to IIS (other techniques are possible, but this approach is perfectly fine). First, you have to create a folder under IIS, ready to receive the deployed application:
      • Open File Explorer and go to the C:\inetpub\wwwroot folder. This is the default web publishing folder for IIS.
      • Create a new sub-folder named Chat (you’ll have to accept the User Access Control message). Note that this is the rootpart of the URL that you specified in the web page earlier (e.g. ws:///Chat/…).
      • Start the Internet Information Services Manager console (the easiest way to do this is to search for inetmgr in Windows).
      • In the Internet Information Services Manager console, in the left-hand side of the console, expand the Sites node. Right-click the Default Web Site node, and then click Add Application.
      • In the Add Application dialog box, create an alias named Chat for the c:\inetpub\wwwroot\Chat folder as shown here:
        T16P2
    • You can now deploy your web application to IIS. You can do this with a few button clicks in Visual Studio. Follow these steps:
      • In Visual Studio, in Solution Explorer, right-click your Chat project. In the popup menu, click Publish.
      • In the Publish Web dialog box, you have to choose a publish profile that contains all the configuration details to enable Visual Studio to know how to publish your application. Obviously, you don’t have a publish profile yet, so let’s create one:
        • Expand the Select or import a publish profile drop-down list, and click the <New…> link.
        • In the New Profile message box, type-in a textual string such as Local IIS Website. It doesn’t really matter what you call it, it’s just a descriptive name!
        • The Connection page appears in the wizard. At the top of the page, in the Publish method drop-down list, click the File System option. In the Target location text box, type-in c:\inetpub\wwwroot\Chat. In the Destination URL text box, type-in https://localhost/Chat. Then click Next.
        • The Settings page appears next in the wizard. Accept all default options, and just click Next.
        • The Preview page appears next, summarising where the application will be published. Click Publish here. This actually causes your application to be published to the IIS folder!
    • If you get any publishing errors (e.g, “Unable to publish…”, it might be because you haven’t started Visual Studio as an Administrator. In this case, close Visual Studio and reopen it as an Administrator, and then try to publish the Chat project again (it remembers your publish profile details!).
    • To verify that the publishing operation succeeded, open File Explorer and go to the c:\inetpub\wwwroot\Chat folder. It should now contain the deployed portion of your project.
    • After all this work, you are now ready to test your application. Open a browser window (e.g. Internet Explorer 10 or Chrome), and enter the following URL:
      https://localhost/Chat
    • This sends an HTTP request to your Web application, which is running under full-blown IIS. At the server, it routes the request to your HomeController class and the Index() action method. This in turn triggers the Index.cshtml view, which returns a regular HTML page to the browser. When the browser loads the Web page, it calls the init() javaScript function, which pops up a prompt for you to enter your name. Here’s mine:
    • View code file.
    • T16P3

    • After you’ve entered your name, init() should then attempt to establish a Web Sockets connection with the server. All being well, you’ll see a connected message appearing on your web page.
    • Type some text into the text box, and press ENTER. The form-submission code should cause this text to be sent to the Web Sockets server. The Web Sockets server should broadcast this message to all current clients (i.e. just you at the moment!). Your Web page should handle the Web Sockets message and display it on the Web page. If you get this, then you have successfully implemented a Web Sockets application!
    • However, if you just keep chatting to yourself all day, it’s not much fun. So open another browser window and browse to https://localhost/Chat again. Enter a different name, and type in some text in the text box. The message should be echoed in both browsers now!
    • Repeat this process several times, to ensure that all clients see each other’s messages (as broadcast from the server).
    • Then close a browser window. This closes the Web Sockets connection, and the server broadcasts a message to all remaining clients to indicate someone has left the Chat Room. Verify that you see this message appearing in all the other browsers.

 

Well done. You have completed the tutorial in the HTML5/CSS3/JS course. The next tutorial is

17. Web Workers


Back to beginning
Copyright © 2016 TalkIT®






If you liked this post, please comment with your suggestions to help others.
If you would like to see more content like this in the future, please fill-in our quick survey.
Scroll to Top