With the rising number of users on the web, there is a growing issue of connectivity, seamless communication, and downtime. People who use the Internet expect a response to their input almost immediately, which means in real-time. The Hypertext Transfer Protocol (HTTP) has been on guard of data sharing without delays for many years. Yet, with the rise of the overload, experts started thinking about different protocols that could handle the influx of user requests. It was the moment when WebSocket entered the picture in 2011.
Since then, WebSockets have proved a crucial tool for building web apps capable of providing instant, real-time updates. Keeping that in mind, to understand how the tool does this, it is vital to explore several key areas — what are WebSockets, how do WebSockets work, why these are useful for building real-time apps, and challenges with WebSockets to consider. Besides, we will go through a step-by-step process of setting up the WebSocket server and client.
In technical terms, a WebSocket is a full-duplex bidirectional protocol using client-server communication as its foundation. In payment terms, a WebSocket is a system or rules programmed for exchanging data between a server and a client in both ways.
Importantly, unlike the WebSocket’s predecessor — HTTP, this protocol starts with we:// or wss// instead of http:// or https://. WebSockets, ensure the server-client connection is ongoing and ceases only when either client or server terminates it.
What are WebSockets used for? As a communication protocol, WebSockets are used for establishing two-way communication between the parties involved, usually a server and a client. The approach ensures a stable and seamless exchange of messages, which entails sending and receiving inputs on both ends.
When it comes to understanding how WebSocket operates, several vital aspects must be considered. Focus on these elements:
Considering the steps above, here is what the initial request header looks like:
GET ws://WebSocket.example.com/ HTTP/1.1 Origin: http://example.com Connection: Upgrade Host: WebSocket.example.com Upgrade: WebSocket |
In turn, if the server accepts the request and “agrees” with the upgrade, it sends the following response:
HTTP/1.1 101 WebSocket Protocol Handshake Date: Wed, 16 Oct 2013 10:07:34 GMT Connection: Upgrade Upgrade: WebSocket |
Keep in mind that running the WebSocket protocol layer is based on a Uniform Resource Identifier (URI). These are ws:// and wss://. Without URI, the system won’t run. At this point, knowing when to use WebSockets is crucial to explore its key types.
In a nutshell, WebSockets come in different shapes and sizes. However, when it comes to the well-recognized and widely used ones, you should consider these:
At this point, choosing among the elements above is essential in finding the WebSocket solution to meet your business needs. In the context of this article, we will focus on WebSockets with an emphasis on real-time applications.
In most cases, WebSockets are best suited for developing real-time applications. The process requires a constant data display on the client’s end. Essentially, as a part of the app’s backend framework, the server sends data to the client, and WebSocket ensures this data stream is uninterrupted and stable. As a result, a real-time app performs steadily, and a user gets a great experience using the product.
Moreover, when helping build real-time applications, WebSockets offers the following unique features:
With the insights above, sufficient evidence suggests WebSockets are crucial for building real-time applications. With the established context, it is time to proceed to a practical guide for setting up a WebSocket server and a client.
When setting up a WebSocket server, there are several key steps to follow and various prerequisites to consider. When preparing the server, you must choose which programming language and library to use.
Starting with system requirements, the key aspect behind setting up a WebSocket server is to have TPC up and to run and listen to incoming connections. Writing a WebSocket server without any external dependencies is possible in such a case. It means it will run on a TCP library only.
However, several options exist considering external languages and libraries:
These are well-recognized programming languages and libraries used to set up a WebSocket server. Yet, when dealing with this protocol, you will find out that WebSocket libraries are basically located on top of different libraries, for instance .NET.
In addition, with WebSocket servers, you need to consider creating WebSocket proxies. Any communication within WebSockets can be in place only when forward proxies are in place. Yet, along with setting the server, you also need to configure proxies properly.
Finally, there is a matter of Server-Sent Events (SEEs) vs. WebSocket. In a nutshell, SSEs are mono-directional, while WebSockets are bidirectional. In such a case, if you need push functionality added to your real-time app, both are options to consider. At this point, the elements above are the ones to look at before starting with the WebSocket server.
To create the WebSocket server, we have chosen a JavaScript library. Without further ado, let’s proceed to the server setting up process, which entails four steps:
As mentioned above, WebSockets need to have HTTP to build upon them. To set up a WebSocket server, you first need to set up a basic HTTP server. This server will be capable of accepting connections and serving messages. So, start by creating server.js file and include the following code:
package main import ( "fmt" "net/http" ) func main() { http.HandleFunc("/", func (w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Setting up the server!") }) http.ListenAndServe(":8080", nil) } |
Then, you should run the server with go run server.js. If you have done everything correctly, when visiting localhost:3000, you will see this — Setting up the server!
With an HTTP server running, you need to set up a WebSocket connection with a one-time handshake. In short, as we mentioned at the beginning of the article, to get the WebSocket protocol, you need to upgrade the server above. It is done through Upgrade() method. Besides, to close the connection, you need to defer keyword. At this point, modify server.js file by including the following code:
conn, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Print("upgrade failed: ", err) return } defer conn.Close() |
After having the WebSocket protocol, the next step is to create a new WebSocket connection. To do that, you need to use this function:
// Create a new WebSocket. var socket = new WebSocket('ws://echo.WebSocket.org'); |
You can change the
// Show a connected message when the WebSocket is opened. socket.onopen = function(event) { socketStatus.innerHTML = 'Connected to: ' + event.currentTarget.url; socketStatus.className = 'open'; }; |
To send messages, you need to add sell() method to the WebSocket protocol. To do that, update your server.go with the following code:
// Send a message when the form is submitted. form.onsubmit = function(e) { e.preventDefault(); // Retrieve the message from the textarea. var message = messageField.value; // Send the message through the WebSocket. socket.send(message); // Add the message to the messages list. messagesList.innerHTML += ' ''; // Clear out the message field. messageField.value = ''; return false; }; |
The code indicates that the message needs to be retrieved and sent through the Webscoket protocol. When receiving the message, the particular event must be fired. Besides, the event must include a property to access the message itself. Let’s name these as message event and data property. Receiving messages comes with this code:
// Handle messages sent by the server. socket.onmessage = function(event) { var message = event.data; messagesList.innerHTML += ' message + ''; }; |
As a result, with the server above, you can initiate the handshake and have features for sending and receiving messages. It is time to set up a client as a second part of the equation.
Setting up a WebSocket client includes some elements comparable to setting up a WebSocket server. Yet, there are particular differences involved as well. Let’s take a look at both of them more closely.
First and foremost, you must choose programming languages and libraries to use as the foundation. You can select these well-recognized options from:
Moreover, if nothing from above suits your purposes, you can always choose from WebSocket’s internal libraries. These can be SockJS, Socket.io, and/or WS.
Next, after choosing the needed programming language and library, it is time to deal with the WebSocket test client. It is a simple yet useful tool to design custom-made WebSocket requests and handle responses. This allows you to test WebSocket services directly. To use the WebSocket test client, follow these steps:
At this point, following the aspects above presents the key prerequisites for setting up a WebSocket client. Furthermore, you proceed with creating a WebSocket client itself.
For our Webscoket client, we will use JavaScript Object Notation (JSON) format. The reason for such a choice is that it is lightweight and easy to read and write. So, to set up a WebSocket client with JSON, you need to follow these four steps:
First and foremost, to communicate through a WebSocket protocol, you need to open an automatic connection with a WebSocket server by creating a WebSocket object. Consider this parameter:
WebSocket = new WebSocket(url, protocols); |
In the code, instead of url, type in the URL to which the WebSocket server will respond. It should use the wss:// configuration. In terms of protocols, the software will assume an empty string if there is no specification of which protocol string should be used. Keep in mind if you use an insecure connection, the WebSocket constructor will indicate a SecurityError.
If there are no security errors in the previous step, you have your WebSocket object intact. Now, it is time to transmit data to the server. Use send() method for each message you send. It will look like this:
exampleSocket.send("Lorem Ipsum!"); |
Yet, sending a message right after the WebSocket object was created does not mean you will succeed at once. Asynchronous connections are prone to fail. To raise your chances of success, define an onopen event handler. Now, the new code will look like this:
exampleSocket.onopen = (event) => { exampleSocket.send("Lorem Ipsum!"); }; |
The method above is good for sending simple messages. However, if you need to transmit complex data to the WebSocket server, it is better to use frameworks like JSON. In such a case, the code will be the following:
// Send text to all users through the server function sendText() { // Construct a msg object containing the data the server needs to process the message from the chat client. const msg = { type: "message", text: document.getElementById("text").value, id: clientID, date: Date.now() };
// Send the msg object as a JSON-formatted string. exampleSocket.send(JSON.stringify(msg));
// Blank the text input element, ready to receive the next line of text from the user. document.getElementById("text").value = ""; } |
Now, when you have written the code for a WebSocket object and sent messages to the server, it is important to take the next step — write code for receiving data from the server to the client.
As an event-driven API, WebSockets works so that when data is received, a message event is directed to the WebSocket object. In such a case, to deal with it, you need to use onmessage handler. As a result, you should get something like this:
exampleSocket.onmessage = (event) => { console.log(event.data); } |
The further substep is all about getting and interpreting JSON objects. The code interpreting the messages coming to the client should include the elements like login handshake, the text of the message, and user list updates. These are the code:
exampleSocket.onmessage = (event) => { const f = document.getElementById("chatbox").contentDocument; let text = ""; const msg = JSON.parse(event.data); const time = new Date(msg.date); const timeStr = time.toLocaleTimeString(); switch (msg.type) { case "id": clientID = msg.id; setUsername(); break; case "username": text = `User ${msg.name} signed in at ${timeStr} break; case "message": text = `(${timeStr}) ${msg.name} : ${msg.text} break; case "rejectusername": text = `Your username has been set to ${msg.name} because the name you chose is in use. break; case "userlist": document.getElementById("userlistbox").innerHTML = msg.users.join(" break; }
if (text.length) { f.write(text); document.getElementById("chatbox").contentWindow.scrollByPages(1); } }; |
Keep in mind that messages received from the WebSocket forms are in UTF-8 format.
Finally, when the client-server connection is complete, and you are finished with sending and receive messages, you need to close the connection with close() WebSocket method. Ceasing the connection looks like this:
exampleSocket.close(); |
At this point, you know how to initialize both ends of the WebSocket protocol and exchange data. Yet, keep in mind that WebSocket should not be utilized when mixed content is involved, namely because there are security considerations involved.
What are WebSockets used for? We presented the general answer to this question above. While Websockers are great for real-time apps, the protocols can also be used for the following purposes:
As a result, you can see how WebSocket can help build real-time apps with different adoptions. From chatting to data visualization, this protocol offers speed and flexibility. Besides, it can work with multiple clients at the same time.
If you want your app to use WebSocket protocol properly while also maintaining performance and downtime, here are seven tips to consider.
The tips above are crucial for starting with real-time apps and WebSockets. The more such apps you build, the more you understand the value of concepts like latency, security, and bandwidth.
When it comes to WebSockets security, you cannot go light. To do your best with WebSockets, you must know what typical challenges may arise. So, be prepared to deal with these issues:
So, let’s sum up all of the above. What is a WebSocket? It is a fast and flexible protocol that came out as a substitute for HTTP. When to use WebSockets? When you need to build a real-time app, to have to send and receive data without delays. What is WebSockets used for? They are used for multiple things, from chatting apps to collaborative apps. One can say that shortly, the list will be even longer. Yet, with both WebSockets and HTTP, you need to prioritize security and keep in mind that any app out there should provide high-quality services.
Andriy Lekh
Other articles