What is WebSocket?

WebSocket is a two-way computer communication protocol over a single TCP. This is the common definition for it. Using WebSockets is a good way to handle high scale data transfers between server-clients. You can find many definitions like that on the simple Google (or Bing :)) search.

But,

I want to expand on this topic by giving some simple and purposeful examples.

websocket

How can we develop a WebSocket Server?

Generally, choosing a framework/library is very easy for us/developers. Because we usually use our main language and our main language’s most popular/useful library to develop something :).

There are many ways in many languages with many libraries. Some of them are in the following.

Also, you can find a wide list here. As you can imagine, As a Front-End developer, I’ll give you some examples with the Node.js server 🙂

Lets we begin coding without further ado!

Don’t miss out the latestCommencis Thoughts and News.

How can we create a web socket server with Node.js?

I will use the Socket.io creating a web socket server.

Before the start, there is something that you need to know;

Socket.io library needs to the Express.js library. Express.js is the biggest web framework for Node.js. You can develop a Web Application, a Web API or both of them in the same place with it.

Creating Instances

//Create a web application instance
const app = require("express")();

//Create a http server
const http = require("http").createServer(app);

//Create a socket server instance
const io = require("socket.io")(http);

As you can see, you need 2 major library/module while generating a simple web server, and 1 library for WebSocket. I’ve already described Express.js in above.

So what is HTTP/createServer?

HTTP is a built-in Node.js module to transfer data over HTTP. You can find official documentation in here.

Creating A Web Server

//Homepage defitinion of Web Server (ex: http://localhost:3000)
app.get("/", function(req, res) {
   res.send(`<h1>Web Server is Running...</h1>`);
});

//Start the web server engine with the spesific port
http.listen(3000, function() {
   console.log("listening on *:3000");
});

There are two function calls that are important.

  1. http.listen: This is the server starter function with the all above configurations.
  2. app.get: This is a route definition function. “/” is the root path of the web server. You can specify any definition as you want. Examples;

/: http://localhost:3000/

/a: http://localhost:3000/a

/a/b/c: http://localhost:3000/a/b/c

Creating A WebSocket Server

I’ve already defined “io” constant via the Socket.io library.

io.on("connect", function(socket) {
   console.log(`A user connected`);
});

As you can see, We’ve added a “connect” event handler to socket instance.

What is “connect”?

“connect” is a major event on socket instance that is used for handle client connections. All client connections should be caught in this handler because of communication. As you can see, this handler has a parameter called “socket”, this has all of the client information that was connected. You can send a message to this client with this object. For example; If you want to show the number of connected clients, you should add an “increase” logic here like the following lines that mentioned with “//Added Line”.

var connectedClients = 0; //Added Line
io.on("connect", function(socket) {
   connectedClients++; //Added Line
   console.log(`A user connected`);
});

Well, we’ve added the increasing logic in the “connect” event. And then, we should add a “decrease” logic in somewhere around here;

What is “disconnect”?

“disconnect” is another important event for us. We can handle all client disconnection logic in here. But don’t forget! This event isn’t io object’s member, this is a socket object’s member.

var connectedClients = 0;
io.on("connect", function(socket) {
  connectedClients++;
  console.log(`A user connected`);
  
  //Added Lines: Start
  socket.on("disconnect", function() {
    connectedClients--;
    console.log(`A user disconnected`);
  });
  //Added Lines: End
});

We’ve completed client counting implementation. Now, we want to show the number of clients on all clients. We need an “event” for that. You are free to choose a name. In this example, we are using “client_count”.

What is “emit”?

“emit” is a function that is using for sending data from client to server or server to client. If you call this function from the “io” object, you send data to all clients. But, If you call this function from the “socket” object, you send data to a specific client. In this case, we want to send data to all client when client counter has changed, therefore we will use emit function from “io” object.

var connectedClients = 0;
io.on("connect", function(socket) {
  connectedClients++;
  console.log(`A user connected`);
  
  //Added Line
  io.emit("client_count", clientCounter);
  
  socket.on("disconnect", function() {
    connectedClients--;
    console.log(`A user disconnected`);
    
    //Added Line
    io.emit("client_count", clientCounter);
  });
});

Yes! We’ve developed the server side for the handle client connection, disconnection and messaging.

The next is the client side!

How can we develop a WebSocket Client?

Development is simple for client-side like server-side development. Everything is easier now because we don’t need choosing one of frameworks or libraries except socket.io. It’s simple web development as you want and as you are used to.

First of all, you should create an HTML file to be developed like that. I’m using jQuery for these examples. If you don’t want, you can use built-in javascript functions. After the creation, you can add the following scripts in the <head></head> tags.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>title</title>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
    
  </head>
  <body>
    
  </body>
</html>

If you don’t want to use CDN, you can download these files and use them from local.

After that, we can add the following lines to the socket connection.

$(document).ready(function() {
   var socket = io("localhost:3000");
});

As you know, “localhost” is the development environment for us and “3000” is the port number that we specified.

As you can see only one line is enough for the connection to the server. After this line execution, the “connect” event will be triggered on the server-side. The connection is ready for the displaying number of connected clients with the “client_count” event.

$(document).ready(function() {
  var socket = io("localhost:3000");
  
  //Added Lines: Start
  socket.on("client_count", function(data) {
    $("#client_count").html(`${data} client(s) connected`);
  });
  //Added Lines: End
});

That’s it!

We’ve connected to the client and the server successfully. We’ve created a connection and send data from the server to all clients.

Now, We can add a “subscription” example.

How to create a group (room) and subscribe to it from the client?

What is the room?

The room is a group that is using for clients separation. You can think it is a chat room. As you know, chat rooms isolated from other ones. For example, you can join a room and chat with peoples that are in this room, not everyone, only the room’s participants.

You can find a lot of examples for socket usage. But in this example, we will develop based on temperature tracking logic.

Suppose we have an aquarium and a thermometer for it. And we want to track every temperature change from an IoT device. In this case, your tracking website and the IoT device are the clients. A client (IoT) sends data (temperature) to the server and the server sends this information to all subscribers (website). We will develop another web page to simulate the IoT device for this example.

We can start now!

First of all, we should create an event called “update_temperature” for getting the temperature from the source. Update server code like the following;

var connectedClients = 0;
io.on("connect", function(socket) {
  connectedClients++;
  console.log(`A user connected`);
  
  io.emit("client_count", clientCounter);
  
  socket.on("disconnect", function() {
    connectedClients--;
    console.log(`A user disconnected`);
    io.emit("client_count", clientCounter);
  });
  
  //Added Lines: Start
  socket.on("update_temperature", function(temperature) {
    console.log("Temperature:", temperature);
  });
  //Added Lines: End
  
});

Secondly, we should create an event called “join_grp_temperature” for clients subscribe to “grp_temperature” named group.

var connectedClients = 0;
io.on("connect", function(socket) {
  connectedClients++;
  console.log(`A user connected`);
  
  io.emit("client_count", clientCounter);
  
  socket.on("disconnect", function() {
    connectedClients--;
    console.log(`A user disconnected`);
    io.emit("client_count", clientCounter);
  });
  
  socket.on("join_grp_temperature", function(temperature) {
    //Added Line
    socket.join("grp_temperature");
  });
  
  socket.on("update_temperature", function(temperature) {
    console.log("Temperature:", temperature);
  });
});

Now, “grp_temperature” is ready for communication with participants. So when should we send a temperature value to participants? Answer: in the “update_temperature” event. Because we are using this event to getting new temperature value from IoT device.

var connectedClients = 0;
io.on("connect", function(socket) {
  connectedClients++;
  console.log(`A user connected`);
  
  io.emit("client_count", clientCounter);
  
  socket.on("disconnect", function() {
    connectedClients--;
    console.log(`A user disconnected`);
    io.emit("client_count", clientCounter);
  });
  
  socket.on("join_grp_temperature", function(temperature) {
    socket.join("grp_temperature");
  });
  
  socket.on("update_temperature", function(temperature) {
    //Added Line
    io.to("grp_temperature").emit("temperature", temperature);
  });
});

As you can see, we’ve used the “emit” function again to send data to the clients. But with only 1 difference. We’ve used “to” function before the “emit”. “to” function is using to select a room.

Now, we’ve completed to server-side development. The last step is the client-side.

Firstly, we need to join “grp_temperature”.

$(document).ready(function() {
  var socket = io("localhost:3000");
  
  socket.on("client_count", function(data) {
    $("#client_count").html(`${data} client(s) connected`);
  });
  
  //Added Lines: Start
  $("#btn_joinGroup").click(function() {
    socket.emit("join_grp_temperature");
  });
  //Added Lines: End
});

Lastly, we need to attach to the “temperature” event to receive updated values.

$(document).ready(function() {
  var socket = io("localhost:3000");
  
  socket.on("client_count", function(data) {
    $("#client_count").html(`${data} client(s) connected`);
  });
  
  $("#btn_joinGroup").click(function() {
    socket.emit("join_grp_temperature");
    
    //Added Lines: Start
    socket.on("temperature", function(temperature) {
      console.log("Temperature:", temperature);
    });
    //Added Lines: End
  });
});

Finally, I have embellished this development for you.

Conclusion

WebSockets present a simple solution to huge problems. Easy integration, easy implementation, lightweight coding are tempting solutions.

In this article, I tried to address frequently asked questions on WebSocket from my point of view. I hope this will be helpful for you. If you want to discuss further on the subject, you can contact me on Twitter.