JUMP START HTML5 (2014)
Chapter 30 APIs: The WebSocket API
I think that WebSockets are one of the coolest APIs available in HTML5. The real strength of the WebSocket API comes to the fore when you want your clients to talk to the server through a persistent connection. This means that once the connection is opened, the server and the client can send messages to each other anytime. Gone are the days when clients used to send a message to the server and wait until the server responded back. Clearly, WebSockets eliminate the need for long polling! The API is very useful if you want to create real-time apps where clients and the server talk to each other continuously. For instance, you can build chat systems, multi-player HTML5 games and similar apps with WebSockets.
Note: WebSockets versus Server Sent Events (SSEs)
WebSockets and SSEs can achieve similar tasks but they are different. In the case of SSEs, the server only pushes data to the client once new updates are available. In the case of WebSockets, both client and server send data to each other; to be precise, the communication is bi-directional (full-duplex, if you love more technical terms).
To use WebSockets, you’ll need a WebSocket-enabled server. Well, that’s the tricky part. Don’t worry! There are implementations of WebSockets available for several different languages. I will cover those shortly.
Additionally, you should always bear in mind that WebSockets allows cross-origin communication. So, you should always only connect to the clients and servers that you trust.
The JavaScript API
Let’s quickly try it out. The developers at WebSocket.org have created a demo WebSocket server at ws://echo.websocket.org. We can connect to it and start exchanging messages with it in no time.
Note: The ws:// Protocol
ws:// is a protocol that’s similar to http://, except that it’s used for specifying the Web Sockets server URLs.
First, let’s see how to connect to a simple WebSocket server using the JavaScript API. After that, I will show how you can create your own WebSocket server and let others connect with you.
// test if the browser supports the API
if('WebSocket' in window) {
var socket = new WebSocket('ws://echo.websocket.org');
if (socket.readyState == 0) console.log('Connecting...');
// As soon as connection is opened, send a message to the server
socket.onopen = function () {
if (socket.readyState == 1) {
console.log('Connection Opened');
socket.send('Hey, send back whatever I throw at you!');
}
};
// Receive messages from the server
socket.onmessage = function(e) {
console.log('Socket server said: ' + e.data);
};
socket.onclose = function() {
if (socket.readyState == 2) console.log('Connection Closed');
};
// log errors
socket.onerror = function(err) {
console.log('An Error Occurred ' + err);
};
}
else {
// sadly, no WebSockets!
}
Note: Using Modernizr
With Modernizr, we can check for the browser support of WebSockets this way:
if (Modernizr.websockets) {
// proceed
}
else{
// No WebSocket
}
So, you start by passing the socket server URL to the WebSocket constructor. The constructor also accepts an optional second parameter, which is an array of sub-protocols. This parameter defaults to an empty string.
Next, we attach different callbacks for different events. As soon as the connection opens, the onopen event is fired and our callback executes. You can send a simple message to the server by calling socket.send(). You can also send binary data, which we’ll see in the next section.
Similarly, the server can also send us messages. In that case, the onmessage callback fires. At the moment, the server sends us back whatever we send to it, and we simply log the message received. But you can always capture the message and dynamically update your page with it.
Just paste the code in an HTML file and run it ― you’ll be delighted to see the server’s response!
Note: The readyState Property
The variable socket in the aforementioned code has a property called readyState indicating the status of the connection:
· 0 = connecting
· 1 = opened
· 2 = closed
Sending Binary Data
You can also send binary data to the server. The following program sends the image drawn on canvas to a sample WebSocket:
// you need to create this socket server
var connection=new WebSocket('ws://localhost:8080');
connection.onopen = function() {
// get an image from canvas
var image = canvas2DContext.getImageData(0, 0, 440, 300);
var binary_data = new Uint8Array(image.data.length);
for (var i = 0; i < image.data.length; i++) {
binary_data[i] = image.data[i];
}
connection.send(binary_data.buffer); // send the data
}
In the code, we read the image from the HTML page and create an ArrayBuffer to contain the binary data. Finally, connection.send() actually sends the data.
Note: Using Blobs
We can also send the binary data as a blob. For example, you could create a file uploader and read the files through querySelector(). Then you can send those files with the help of connection.send(). HTML5Rocks has an excellent tutorial on WebSockets that also covers sending binary data to the server through blobs.
Sample Server Implementations
Here are a few WebSockets implementations available for different server-side languages. You can choose a library based on your preferred language:
· PHP: Ratchet
· Node.js: Socket.IO
· Java: jWebSocket
For a complete overview of server-side libraries, Andrea Faulds maintains a comprehensive list.
It’s beyond the scope of this short book to discuss each of these libraries in detail. But regardless of the implementation, they all offer a simple API through which you can interact with your clients. For example, they all offer a handler function to receive messages from the browser and you can also communicate back with the client. I encourage you to grab a library for your favorite language and play around with it.
I have written an extensive tutorial on WebSockets on SitePoint.com. In that tutorial, I’ve shown how to implement a WebSockets-enabled server using jWebSocket and let others connect to it.
Conclusion
If you want to learn more about the WebSocket API, the following resources are worth checking out:
· the WebSocket API
· WebSocket tutorial at Mozilla Ddeveloper Network
· WebSocket demo apps
Here are a few use cases of the API:
· creating a simple online chat application
· updating a page as new updates are available on the server and communicating back
· creating an HTML5 game with multiple users.