From my previous part of the learning HTML5 series articles you already have a basic introduction to the HTML5 APIs and Web Workers that provide a way in JavaScript to run something in the background that can do tasks without interfering with the user interface and Server-sent Events APIs in combination with the EventSource API designed for streaming updates. If you want to review it then follow the following links:
Now in this part of series we will focus on the WebSocket API a bidirectional communication channel.
WebSocket API
WebSockets provide a richer protocol to perform bi-directional communication and we can create a full-duplex communication channel that can be operate through a single socket over the Web and for that reason its more attractive for things like games, messaging apps and for real-time updates in both directions.
In my last article I said "WebSockets are used very much and tons of server implementations are available on the internet. However the second server-push technology of HTML5 yet stays in the shadows." and the the second server-push technology of HTML5 is Server-Sent Events (SSE). So, why does SSE stay in the shadows? The reason behind that is that WebSockets has many exciting features over SSE like a richer protocol to perform duplex communication, very efficient, low-latency and too low in cost connection between client and server and providing an enormous reduction in unnecessary network traffic.
The following are clear advantages of Websockets over SSE:
- Real-time communication but in two directions
- Native support in more browsers
Browser Support
Image Source : http://caniuse.com/websockets
Need for WebSocket
Now for web communication we used a request-reply protocol that is HTTP and for desktop communication we used polling, long polling and streaming. Now here is the problem that these are all communication methods use HTTP protocol and HTTP protocol contains lots of unnecessary header information, like request coming address, heading, user agent information and so on and due to all this bulky information the bandwidth is affected in real-time scenarios and as usual is not a full-duplex communication.
WebSocket is basically used to reduce the overhead of HTTP and how it is reduced, since it has its own protocol defined by IETF and an API for server communication. By using them the client notifies the web-socket server with the recipients id of an event and the server immediately notifies all the active clients and the last clients process the event when the given recipient Id matches the client Id.
Websocket.org releases experimental results of comparing the performance of polling and WebSocket in detail. In this experiment they work with two web pages, wherein one used polling and the other used WebSocket to communicate with the server.
- Polling
Use case A : 1,000 clients polling every second: Network throughput is (871 x 1,000) = 871,000 bytes = 6,968,000 bits per second (6.6 Mbps)
Use case B : 10,000 clients polling every second: Network throughput is (871 x 10,000) = 8,710,000 bytes = 69,680,000 bits per second (66 Mbps)
Use case C : 100,000 clients polling every 1 second: Network throughput is (871 x 100,000) = 87,100,000 bytes = 696,800,000 bits per second (665 Mbps)
- WebSocket
Use case A : 1,000 clients receive 1 message per second: Network throughput is (2 x 1,000) = 2,000 bytes = 16,000 bits per second (0.015 Mbps)
Use case B : 10,000 clients receive 1 message per second: Network throughput is (2 x 10,000) = 20,000 bytes = 160,000 bits per second (0.153 Mbps)
Use case C : 100,000 clients receive 1 message per second: Network throughput is (2 x 100,000) = 200,000 bytes = 1,600,000 bits per second (1.526 Mbps)
Graphical Representation
Key Features of WebSocket
- WebSocket is a richer protocol to perform bi-directional communication
- Its a full-duplex communication channel that can operate through a single socket over the web, your request reuses the same connection from the client to the server and the server to the client.
- Since it makes a single request and the single request greatly reduces the latency over polling
- Communication becomes much more efficient since bandwidth, CPU power and latency is saved
- You can build other standard protocols on top of its protocol
- WebSocket is a feature that makes HTML5 more advanced
- WebSocket is about simplicity
How WebSocket works
WebSocket works in the following two parts:
Before the client and server start sending and receiving messages, first the connection must be established and this is done by a handshake. Here the protocol ensures that the HTTP based clients and WebSocket can be operated on the same port and the client sends a request for connection and if the server wants the connection then it will send a response to accept the connection. The initiating handshake by the client upgrades the client and server from an HTTP based protocol to a WebSocket based protocol.
Some of the technologies widely used for WebSocket server implementations are:
- .NET
- Fleck
- ASP.NET 4.5
- SuperWebSocket
- XSocket.NET
- Java
- jWebSocket
- JettyWebSocket
- Node.js
Sample applications where you can use WebSocket:
- Social feeds
- Gaming
- Streaming Apps
- Financial updates
- Sports updates
- Chat platform
- Location-based apps. Like GPS enabled apps
- Online Support
Let's summarize WebSocket implementation with a simple example.
First get the WebSocket Server
Step 1 : Download node.js from here and install it.
node.js is a JavaScript runtime platform for creating easily built, fast, scalable network real-time applications.
Step 2 : Install "socket.io". To install first run command prompt and go to your node.js location run the following "socket.io" installation command:
socket.io lightweight API that runs on the browser
Step 3 : Now initiate a server in node.js and for that you need to a create js file and just initiate a server in just the following three lines of code.
- var http = require('http');
- var io = require('socket.io');
- var myserver = http.createServer().listen(1000);
Step 4 : Now for sending something to the client from the server create an anonymous function that defines what happens with each request and in that function we define how we are sending data to the client. All elements are declared by writeHead are written to the response header.
- var myserver = http.createServer(function (request, response) {
- response.writeHead(250, { 'Content-Type': 'text/html' });
- response.end('Your server is running');
- }).listen(1000);
Step 5 : Now enable your server to receive a message from the client.
- var mysocket = io.listen(myserver).set('logmessage', 1);
- mysocket.on('connection', function (client) {
- client.on('message', function (data) {
- console.log('Client Message: ', data);
- var current = new Date().getTime();
- client.emit('MessageResponse', data + '->' + current);
- });
Step 6 : Start the server by calling the js file in the command prompt.
Start Building the Client
Step 1 : Create a HTML file and pass the reference of the js file in the head section as in the following:
- <head>
- <script src='http://localhost:22222/socket.io/socket.io.js'></script>
- </head>
Step 2 : Here initialize the function and connect to the io.
- var MySockets = {};
- MySockets.socketio = {
- yoursocket: null,
- initialize: function () {
- MySockets.socketio.customsocket = io.connect('http://localhost:1000');
- });
}
At this point you have a WebSockets connection between the client and our server and you can send data to the client. But first you need to map a method name to a function and do that with an on method as in the following:
- MySockets.socketio.customsocket.on()
Step 3 : Here very first we trigger a connection action that will send a “message” action to the client.
- MySockets.socketio.customsocket.on('connect', function () {
- MySockets.socketio.log('You are connected to Server<br />');
- });
Step 4 : Now the code to send the message from the client to the server using sendMessageToServer.
- document.querySelector('#sendmessage').onclick = function () {
- MySockets.socketio.sendMessageToServer(document.querySelector('#message').value);
- document.querySelector('#message').value = '';
- };
- sendMessageToServer: function (data) {
- MySockets.socketio.customsocket.send(data);
- MySockets.socketio.log('Message to Server: ' + data + '<br />');
- },
Complete Code of .js file
- var http = require('http');
- var io = require('socket.io');
- var myserver = http.createServer(function (request, response) {
- response.writeHead(250, { 'Content-Type': 'text/html' });
- response.end('Your server is running');
- }).listen(1000);
- var mysocket = io.listen(myserver).set('logmessage', 1);
- mysocket.on('connection', function (client) {
- client.on('message', function (data) {
- console.log('Client Message: ', data);
- var current = new Date().getTime();
- client.emit('MessageResponse', data + '->' + current);
- });
- client.on('disconnect', function () {
- console.log('Your Client disconnected');
- });
- });
Complete Code of .html file
- <!DOCTYPE html>
- <html>
- <head>
- <script src='http://localhost:22222/socket.io/socket.io.js'></script>
- </head>
- <body>
- <script>
- var MySockets = {};
- MySockets.socketio = {
- yoursocket: null,
- initialize: function () {
- MySockets.socketio.customsocket = io.connect('http://localhost:1000');
- MySockets.socketio.customsocket.on('connect', function () {
- MySockets.socketio.log('You are connected to Server<br />');
- });
- MySockets.socketio.customsocket.on('message', function (data) {
- MySockets.socketio.log('Server Response: ' + data + '<br />');
- });
- MySockets.socketio.customsocket.on('disconnect', function () {
- MySockets.socketio.log('You are disconnected from Server<br />');
- });
- document.querySelector('#sendmessage').onclick = function () {
- MySockets.socketio.sendMessageToServer(document.querySelector('#message').value);
- document.querySelector('#message').value = '';
- };
- },
- sendMessageToServer: function (data) {
- MySockets.socketio.customsocket.send(data);
- MySockets.socketio.log('Message to Server: ' + data + '<br />');
- },
- log: function (message) {
- document.querySelector('#logmessage').innerHTML += message;
- }
- }
- </script>
- <div id='logmessage'></div>
- <input type='text' id='message' />
- <button type='button' id='sendmessage'>Send</button>
- <br />
- <script>
- MySockets.socketio.initialize();
- </script>
- </body>
- </html>
All done, run your application. The first time you run the application you can see you are already connected to the server.
Enter your message and press the send button and your message will be sent to the server.
That you can see on your server-side command prompt.
Now if you want to close the connection, just close your command prompt and you can see on the client side a disconnection message will be shown.
SummaryHTML5 Web Sockets provide a simple way to do fast, robust and very efficient communication between the client and the server.