JoinDownload
This is drafted post. Please setdraft: falsein this .mdx file once ready to be published.

Advanced Concepts in WebSocket

6 Min Read

Vyom Srivastava

In the previous article, we discussed the basic concepts in WebSockets. This article will cover the advanced concepts in WebSocket.

How WebSockets work with HTTP2?

Before we dive into how WebSocket works with HTTP2, let us try to understand the working of HTTP2 first. So HTTP2 is the major revision of HTTP 1.1. It uses binary protocol and multiplexing to achieve great improvement over HTTP 1.1. So in HTTP 2, you still make GET, POST requests but you’re using a single TCP with a very efficient socket. As you make requests, I mean multiple requests all of them go into the pipe at the same time and that is called multiplexing. But how does the server differentiate requests if all the requests are in the same pipe and hit the server at the same time and how does the client differentiate the responses? Well, this is where we need the stream id tag. Stream ID is an internal tag that we do not see as a client. Every time we make a request, each packet of the request will be tagged with a stream id. The server will start processing one stream id at a time (could be multiple also in case of multiple threading) and once the client receives the response it starts to map the stream id with the requests to identify the respective responses for the request. This is what goes behind the scenes of multiplexing where we’re tagging everything with a unique stream id. This allows powerful stuff like compressing not just for data but HTTP requests. We do compression in HTTP 1 also but we can’t compress headers in that case since headers let you identify different data but with the idea of stream id in HTTP 2, we already have an identifier so we can compress headers and other sorts of data.

What other benefits do we get from HTTP 2? There’s one more benefit that is not enabled by default like multiplexing and streaming is enabled by default. The benefit is that you can do HTTP 2 with a PUSH also. What does that mean? If your server is smart enough and you configure it in a way so that you make one request to GET an index.html from the server and the server know if someone is requesting index.html they might also need style.css and script.js, so the server can PUSH all of the files together. In other words, the server can PUSH multiple responses for a given request. But that can get a little bit tricky if the client doesn’t support HTTP2.

Now let’s go back to HTTP 1.1 and WebSocket again and imagine you’ve got a WebSocket server and a client. Every WebSocket server is a web server that means it’s listening to port 80 or 443. Once the client establishes the TCP connection, it attempts to communicate with the server with a normal HTTP request having the special upgrade header. Once the request reaches the server or you can say WebSocket server, it responds with 101 which means switching protocol. From now onwards that TCP connection the client created is now just reserved for the WebSocket only. The client can’t do any other task on that TCP connection. If the client wants to send another GET request, it has to make another TCP connection. Obviously, with HTTP 1.1 establishing a TCP connection and having it do only one thing is just a waste of memory because TCP can do a lot more tasks while we can only use it for just WebSockets.

With HTTP2 the above problem was resolved by the use of multiplexing where we can send multiple requests in a pipe and a single TCP connection with stream ids. Everything can be multiplexed together like JSON, CSS, JS, HTTP requests, etc.

Authentication and Query in WebSocket

The WebSocket doesn’t handle Authorization and Authentication on its own. This means that WebSockets can not do the authentication part and doesn’t receive any authentication token. But we can do authorization using some tricks! Since WebSocket always starts with an HTTP request where we pass an upgrade header, here we can pass the Authorization header also. While on the server side we can do authentication as usual. So if you don’t pass the authorization header or the authentication fails then the upgrade also won’t proceed.

The Query works the same as normal, you can pass query parameters in the WebSocket URL and it’ll work fine.

Events in WebSocket

In WebSocket there are four events:

  • open: It means the client has made a successful connection with the WebSocket server.
  • message: This event is fired when a response is received from the WebSocket server.
  • error: This event is fired when the client is disconnected from the WebSocket server due to an error.
  • close: This event is fired when the client is disconnected from the WebSocket server.

States in WebSocket

WebSocket has four states:

  • CONNECTING: This means that the socket has been created but the connection is not open yet.
  • OPEN: This means that the connection is open and ready to connect.
  • CLOSING: This means that the client is trying to disconnect from the WebSocket server.
  • CLOSED: This means that the WebSocket connection is closed.

Data Transfer in WebSocket

In WebSocket the data transfers in small data fragments called “frames”. This frame can be sent from both clients as well as the server-side. There are four types of frame:

  • Text frame: This data frame contains text which client and server send to each other.
  • Binary Data Frame: This data frame contains binary data and is used for true-false values.
  • Ping Pong Frame: These data frames are used to check if the connection is active or not.
  • Service Frame: It contains different data frames like the connection close frame.

Rate Limiting

Rate Limiting is a very nice method to manage data flow in WebSockets especially for clients who are on slow networks. Suppose you’re on a slow network where you have made a WebSocket connection with a server. Now the server is sending data at a very high rate. Now what will happen is that there will be a lot of data that will be lost in the middle because since you’re on a slow network. Now to solve this issue we have to create a buffer that will store the data and push it to the client at the network speed. This helps to recover the data which might get lost in the middle.

Below is the example code for the implementation of the buffer:

setInterval(() => {
if (socket.bufferedAmount == 0) {
socket.send(moreData())
}
}, 100)

The bufferAmount checks for data in the buffer. If there’s no data then only it sends more data to the client else pushes it to the buffer.

Long-Polling vs WebSockets

Long Polling is an alternate method of WebSocket. Many people use Polling as a fallback option for WebSockets, in case WebSocket is not supported. The Long Polling uses HTTP calls to achieve what WebSocket does. It means that it keeps on hitting the server again and again for new data. Once new data arrives, it’s sent to the client. This method is very inefficient and comes under the category of stateless as the client and the server both aren’t aware of each other. One more point to note is that HTTP is not meant for keeping a connection for too long.

While the WebSocket uses the PUSH method where new data is automatically pushed and the client doesn’t have to ping the server again and again for the new data. This is because of the stateful nature of the WebSocket where the client and server both are aware of each other.

WebSocket Example in NodeJS

Now we have learned a lot about WebSocket in this article. Let’s try to create our WebSocket server using NodeJS. Open your terminal and create a new folder by using the below command:

mkdir ws-test

Once done, you can now create open it. After getting inside the folder let’s initialize the project:

npm init

Now we have to install one package called ws:

npm install ws

Once done create a file server.js and paste the below code in that file:

const WebSocket = require("ws")
const wss = new WebSocket.Server({ port: 8080 })
console.log("started")
wss.on("connection", ws => {
ws.on("message", message => {
console.log(`Received message => ${message}`)
})
ws.send("Hello! Message From Server!!")
})

Code Explanation:

Here we are creating a server at port 8080 and then we’re calling the event on the connection. So once the client is connected to the WebSocket server it’ll return a message Hello! Message From Server!! and once the client sends a message it’ll print the message on the terminal.

Now after this let’s test our code. So on your terminal use the below code to start the server:

node server.js

Now open the FireCamp application and select WebSocket from the menu.

In the URL paste this URL: ws://localhost:8080. In the message section, you can send the messages and it’ll be printed on the console: WS Image

Final Words

In this article, we have learned a lot about advanced concepts in WebSockets. The complete chatting system of the social network is based on WebSockets. It opens a wide range of options to make your application more interactive. It’s up to you, how you use it. We tried to cover almost all the aspects of the WebSocket, if we missed any please do let us know in the comment section.

CONTENT
How WebSockets work with HTTP2?Authentication and Query in WebSocketEvents in WebSocketStates in WebSocketData Transfer in WebSocketRate LimitingLong-Polling vs WebSocketsWebSocket Example in NodeJSFinal Words

Links

DownloadDocChange LogsCookiesTerms & ConditionsPrivacy PolicyContact Us

Apps & Integrations

HTTPGraphQLWebsocketSocketIO

Firecamp Newsletter