WebSockets
Websockets help in communication of a backend to other backend or Browser by creating a persistent, full-duplex communication.
The difference between a HTTP and WS server is, the connection is closed to HTTP server soon after receiving a response, which is impersistent. Whereas WS server can send events to client and vice-versa.
Need for other backends:
Example: After a transaction on GPay, the transaction must happen in the primary server as it has more priority and there can be other backend/microservice to send the SMS of the debits/credits which can be asynchronous(can reach the user after some time).
Putting everything in a single big monolith server is a bad idea as other functionality such as sending SMS in above example have less priority and high priority tasks must be served faster. In this case, the messaging API might go down and the clients have to wait for the primary server to free up.
Example for Synchronous communication: HTTP, Websockets(doesn't really wait for response), asynchronous communication: PubSub, Messaging Queues, Server-sent events.
Use Cases for WebSockets:
- Real-Time Applications: Chat applications, live sports updates, real-time gaming, and any application requiring instant updates can benefit from Websockets.
- Live Feeds: Financial tickers, news feeds, and social media updates are examples where Websockets can be used to push live data to users.
- Interactive Services: Collaborative editing tools, live customer support chat, and interactive webinars can use Websockets to enhance user interaction
Note: Some giants still don't use WS, instead they use polling which hits the backend every second or so.
Implementing WS servers:
There are various libraries that let you create a ws server (similar to how express lets you create an HTTP server)
- websocket
- ws
- socket.io (Even though it provides constructs like rooms it will be hard to implement in all platforms i.e Android,..)
WS in NodeJS (Code)
- Initialize an empty Node.js project
npm init -y - Add tsconfig to it
npx tsc --init - Update tsconfig
"rootDir": "./src", "outDir": "./dist", - Install ws
npm i ws @types/ws
Code using HTTP library:
import WebSocket, { WebSocketServer } from 'ws';
import http from 'http';
const server = http.createServer(function(request: any, response: any) {
console.log((new Date()) + ' Received request for ' + request.url);
response.end("hi there");
});
const wss = new WebSocketServer({ server });
wss.on('connection', function connection(ws) {
ws.on('error', (err) => console.error(err));
ws.on('message', function message(data) {
wss.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send(data);
}
});
});
ws.send('Hello! Message From Server!!');
});
server.listen(8080, function() {
console.log((new Date()) + ' Server is listening on port 8080');
});
Whenever we create WS server, we are creating HTTP server under the hood but after sending the request the connection gets upgraded to WS.
Here we are establishing a connection to WS server.
To test it head over to https://hoppscotch.io/realtime/websocket and try establishing a connection
Code using express:
First, install express:
npm install express @types/express
Then, use the following code:
import express from 'express'
import { WebSocketServer } from 'ws'
const app = express()
const httpServer = app.listen(8080)
const wss = new WebSocketServer({ server: httpServer });
wss.on('connection', function connection(ws) {
ws.on('error', console.error);
ws.on('message', function message(data, isBinary) {
wss.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send(data, { binary: isBinary });
}
});
});
ws.send('Hello! Message From Server!!');
});