Skip to main content

This blog post is based on my book “Getting Started with HTML5 WebSocket Programming“, published a few months ago. There’s a special holiday offer for you until the 6th of January.

What is the HTML5 WebSocket protocol?

In real life, handshaking is the act of gently grasping two people’s hands, followed by a brief up and down movement. If you have ever greeted someone this way, then you already understand the basic concept of HTML5 WebSockets.

WebSockets define a persistent two-way communication between web servers and web clients, meaning that both parties can exchange message data at the same time. WebSockets introduce true concurrency, they are optimized for high performance and result in much more responsive and rich web applications. The WebSocket protocol is all about speed: it aims to replace the traditional polling, long-polling and AJAX calls with a native mechanism.

The WebSocket protocol is part of HTML5. HTML5 is a robust framework for developing and designing web applications. It is not just a new markup or some new styling selectors, neither it is a new programming language. HTML5 stands for a collection of technologies, programming languages and tools, each of which has a discrete role and all together accomplish a specific task: building rich web apps for any kind of device. The main HTML5 pillars include Markup, CSS3 and JavaScript APIs. Together.

Unlike what its name implies, the WebSocket protocol is not only about the web! The specification has been implemented from the mainstream mobile and tablet operating systems, including iOS, Android, and Windows. That means you can use the power and speed of the WebSocket protocol into a native smartphone or tablet app. The core principles remain the same, regardless of whether you use JavaScript, Objective-C, or C#.

Throughout this article, we are going to implement a simple chatting web app using WebSockets. No AJAX, no polling, no refresh, no waiting. Here’s the end-result:

Implementing the WebSocket web app

The WebSocket protocol is a new HTML5 feature, so not every browser supports it yet. If you ever tried to run WebSocket-specific code on a browser that is not supported, nothing would happen. Think of your users; it wouldn’t be a nice for them to surf on an unresponsive site. Moreover, you wouldn’t like to miss any potential customers!

JavaScript provides an easy way to find out whether a browser can execute WebSocket-specific code:

if (window.WebSocket) {
    console.log("WebSockets supported.");
    // Continue with the rest of the WebSockets-specific functionality…
}
else {
    console.log("WebSockets not supported.");
    alert("Consider updating your browser for a richer experience.");
}

The WebSocket object

It’s now time to initialize a connection to the server. All we need is to create a WebSocket JavaScript object, providing the URL to the remote or local server:

var socket = new WebSocket("ws://echo.websocket.org");

We are not going to implement the server-side functionality in this blog post, since it would take a few thousands of lines. Instead, we’ll connect to an existing free infrastructure: The example URL “ws://echo.websocket.org” is a public address that we can use for testing and experimenting. Websocket.org server is always up and running and, when it receives a message, it sends it back to the client! It’s all we need in order to ensure that our client-side application works properly.

The WebSocket events

After creating the WebSocket object, we need to handle the events it exposes. There are four main events in the WebSocket API: Open, Message, Close and Error. You can handle them either by handling the onopen, onmessage, onclose and onerror functions respectively, or by using the addEventListener method. Both ways are equivalent, but the first one is much clearer.

Note that, obviously, the functions we’ll provide to our events will not be executed consecutively. They will be executed asynchronously when a specific action occurs.

So, let’s have a closer look at them.

onopen

The onopen event is raised right after the connection between the server and the client has been successfully established.

socket.onopen = function(event) {
    var label = document.getElementById("status-label");
    label.innerHTML = "Connection establisjed!";
}

onmessage

The onmessage event is the client’s ear to the server. Whenever the server sends some data, the onmessage event is fired. Messages might contain plain text, images or binary data. It’s up to you how that data will be interpreted and visualized.

socket.onmessage = function (event) {
    if (typeof event.data === "string") {
        // The server has sent a string.
        var label = document.getElementById("status-label");
        label.innerHTML = event.data;
    }
}

Chapter 4 of the book provides more information about transmitting text, images, binary data and videos.

onclose

The onclose event marks the end of the conversation. Whenever this event is fired, no messages can be transferred between the server and the client unless the connection is reopened.

socket.onclose = function(event) {
	console.log("Connection closed.");
	
	var code = event.code;
	var reason = event.reason;
	var wasClean = event.wasClean;
	var label = document.getElementById("status-label");
	if (wasClean) {
		label.innerHTML = "Connection closed normally.";
	}
	else {
		label.innerHTML = "Connection closed with message " + reason + "(Code: " + code + ")";
	}
}

onerror

The onerror event is fired when something wrong (usually unexpected behavior or failure) occurs. Note that onerror is always followed by an onclose event!

socket.onclose = function(event) {
	console.log("Error occurred.");
	var label = document.getElementById("status-label");
	label.innerHTML = "Error: " + event;
}

The WebSocket actions

Events are raised when something happens. We make explicit calls to actions (or methods) when we want something to happen! The WebSocket protocol supports two main actions: send and close.

send()

While a connection is open, you can exchanges messages with the server. The send() method allows you to transfer a variety of data to the web server. Here is how we can send a chat message (actually, the contents of the HTML text field) to everyone in the chat room:

var textView = document.getElementById("text-view");
var buttonSend = document.getElementById("send-button");
buttonSend.onclick = function() {
	// Check if the connection is open.
	if (socket.readyState === WebSocket.OPEN) {
		socket.send(textView.value);
	}
}

close()

The close() method stands as a “goodbye” handshake. It terminates the connection and no data can be exchanged unless the connection opens again.

var buttonStop = document.getElementById(“stop-button”);
buttonStop.onclick = function() {
	// Close the connection, if open.
	if (socket.readyState === WebSocket.OPEN) {
		socket.close();
	}
}

The result: a blazing fast web app!

And… that’s all! You have just built your first HTML5 WebSocket application. Congratulations. You can also check the index.html file for the markup, the style.css file for the styling, and, of course, the chat.js file for the JavaScript code.

A special offer for Christmas

This blog post was based on my book “Getting Started with HTML5 WebSocket Programming“. As a Christmas deal to you, I have agreed with my publisher to offer this book for just $5 until the 6th of January. So, if you want to develop your first real-time app for the web and mobile, give this book a try.

Vangos Pterneas

Vangos Pterneas is a software engineer, book author, and award-winning Microsoft Most Valuable Professional (2014-2019). Since 2012, Vangos has been helping Fortune-500 companies and ambitious startups create demanding motion-tracking applications. He's obsessed with analyzing and modeling every aspect of human motion using AI and Maths. Vangos shares his passion by regularly publishing articles and open-source projects to help and inspire fellow developers.

5 Comments

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.