We are going to introduce you to the WebSockets technology by programming a very simple chat application.
You will need a basic knowledge of:
- HTML (v5)
- Javascript (ES6)
- Node.js (v8.9.1)
- NPM (v5.7.1)
- jQuery (v3.2.1)
- OS Terminal usage (Win 7, 8, 10 or Linux or macOS)
Before beginning with the example let us take a look at how, in general, the communication between the web browsers and the web servers work.
In order for a web browser to obtain data from a web server, the browser makes a request to the server and then waits for a response. The waiting can be blocking or non-blocking, or synchronous or asynchronous. What those terms mean is that a browser can stop all its code execution till it receives a response (blocking/synchronous) or just continues listening for a server response while it continues executing other tasks (non-blocking/asynchronous).
In this interaction between the web browser and the web server, there are three common traits: the communication is one direction at a time, the server can only send data to the browser after a request was made and the channel of communication is cut off after the response was made.
WebSockets is a communication protocol that allows communication in both directions synchronously through a TCP connection, so this protocol removes the said limitations. Once the browser starts a connection with the server, the communication channel is both ways, the server is not limited to send data only after a request from the browser and the connection is not cut off after a response from the server. Also, the browser doesn’t necessarily need to wait for a response after sending a message to the server.
Now that we know the WebSockets characteristics, we can move on to the example.
In order to run the code of the example, you will need to install Node.js in your computer, you can obtain it through the official site https://nodejs.org/en/, this will also install NPM (Node Package Manager) that you will use to install the project dependencies. Once the Node.js is installed, extract all the files contained in the file websockets.tar.gz into a directory of your choosing and then, inside the chosen directory, type the following to install the project dependencies:
npm i
A directory with the name node_modules will be created containing all the required dependencies.
Now type the following to run the code that will start two simple web servers, one that will listen to WebSockets and another that will server the chat user interface:
npm run start
You can also obtain the same result by just typing the following:
node server
The former command is just an alias that calls the latter.
Leave the terminal open and from a browser of your liking go to http://localhost:8098.
At this point, you have all set up to test this code by yourself.
Now we are going to analyze the code.
First we create the websocket server (server.js) using the ws (v2.3.1) library:
const websocketServer = new WebSocket.Server({
perMessageDeflate: false,
port: 8099
});
And we set to listen to connection:
websocketServer.on('connection', function connection(connection) {
connection.send('Welcome to the chat!!!');
The cool part is the second one, we can see here that once the connection is established with the browser, we send a message without the browser ever requesting anything.
In the next line we listen for browser calls.
connection.on('message', function (message) {
At this point we have two options, send back a response to the browser or not. In this case we broadcast the message to all the browsers connected to the server:
websocketServer.clients.forEach(function (client) {
if (client.readyState === WebSocket.OPEN) {
client.send(message);
}
});
The rest of the code in this file is to create the web server that will provide the chat user interface, to accomplish this task we are going to use express.js (v4.15.2).
On the client side, client.js things are simpler. The browser will listen for incoming messages from the server using the native implementation of websockets (i.e. without external dependencies like ws on the server).
websocketConnection.onmessage = function (event) {
var message = event.data;
consoleScreen.append(message + '<br>');
console.log('Received: ' + message);
};
And also the browser will be aware if the connection is established or if it’s lost.
websocketConnection.onopen = function() {
consoleScreen.append('Connection opened.<br>');
};
websocketConnection.onclose = function() {
consoleScreen.append('Connnection lost.<br>');
};
You can test further how this mechanism works if you open the address http://localhost:8098 on several tabs on your browser or even on different browsers. Also, if your server is available inside a network, you can test this by using browsers in several computers, in this last case you need to edit the client.js line:
var chatAddress = 'localhost';
Instead of ‘localhost’ you need to write the ip address of the computer that is hosting the server.
As a final explanation, we are going to show you, by mean of simple illustrations, an interaction between the components of our software.
In the first frame of the illustration, Client A is sending a message to the server, here represented by a line with an arrow indicating the direction of the communication. Keep in mind that all clients have a live connection with the server at all times represented by a dotted line when they are not receiving or sending messages.
In the second frame the server is relaying the message of Client A to the other connected clients, but at the same time Client C is now sending a message to the server.
In the last frame, the server is relaying the message of Client C to the other clients. This time none of the other clients is sending a message.
You can see all this in action if you follow the steps so far. Here you can get the full code to start.
Have fun!