WebSockets
Tags: nextjs, websockets, backendcommunication, communication
Published: 2024-05-16 20:34:54

# WebSockets

### What

**Websockets** is a way to talk to server, Just like http. It is generally established between a Frontend and a Server.

It is a `Persistant` & `Full Duplex Communication`.Unlike `http` in which connection is closed after getting the response & also is not full duplex.

### Why

It can be used where we want the connection to be persistant or when instead of frontend have to ask for the response multiple times the server can send the response when it is cooked.

**Why not use HTTP in these cases**

- if we use http then we have to send req every sec/minute asking server the info - this technique is called pooling, used by LeetCode.
![Leetcode](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8yd44rywxcnngz8abbw3.png)


- It's better when the info is cooked the server sends it to you, instead of asking multiple times to the server.
- But there is a **drawback** also, a server can handle multiple http request but a server can only 10-20k websocket connection, due to it's persistant nature. In http, the connection closes once respones is received.

### When

- 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

Example : In a Crypto Exchange , where price needs to be updated every second.

![Crypto Exchange](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4cxjyquvp96yn7z6zzt1.png)

### How

There are various libraries that let you create a ws server (similar to how express lets you create an HTTP server)
https://www.npmjs.com/package/websocket
https://github.com/websockets/ws
https://socket.io/

But we will be using ws library.

`Under the Hood first a Http Connection is established then it is upgraded by the server to Websocket.`

1. **Using Node.js**

```ts
import express from "express";
import ws, { WebSocketServer } from "ws";

// create an http server , then it is upgraded to websocket
const app = express();

app.get("/", (req, res) => {
	res.send("Hello, World!");
});

let httpServer = app.listen(8080, () => {
	console.log("Listening on Port", 8080);
});

// Intializing a webSocketServer
const wss = new WebSocketServer({ server: httpServer });

wss.on("connection", function connection(ws) {
	// from client to all other client expect itself.
	ws.on("message", function message(data, isBinary) {
		wss.clients.forEach(function each(client) {
			if (client !== ws && client.readyState === ws.OPEN) {
				client.send(data, { binary: isBinary });
			}
		});
		console.log("received: %s", data);
	});
	// server to all the clients
	ws.send("Hello, World!");

	// In case of Multiplayer games there is a single source of truth the server.Only server sends the data to all clients and clients sends the data to server, no client to client.
});
```

To Run above code, Run the server on port:8080, then go to [Hoppscoth](https://hoppscotch.io/realtime/websocket), and paste this in URL - `ws://localhost:8080` & your websocket connection is established.

2. **Using Next.js**

So Same like fetch we have a Browser API called `webSocket` then we can use to communicate.

```tsx
// It should be a client side Component, cuz In serveless webscokets is hard cuz a serverless server goes up and down very quickly, so there is no good to establish a persistant connection.
"use client";
import { useEffect, useState } from "react";

export default function Home() {
	const [socket, setSocket] = useState<WebSocket | null>(null);
	const [message, setMessage] = useState("");

	useEffect(() => {
		const socketClient = new WebSocket("ws://localhost:8080");

		socketClient.onopen = () => {
			console.log("Connection Established");
			socketClient.send("Hello Server");
		};

		socketClient.onmessage = (message) => {
			console.log("Message Received", message.data);
			setMessage(message.data);
		};

		setSocket(socketClient);

		// in strict mode the code runs twice , so
		return () => socketClient.close();
	}, []);

	if (!socket) {
		return <div>Loading...</div>;
	}
	return <>HELLO {message}</>;
}
```