โšก Different Ways to Implement Real-Time Communication Between Client and Server

KUNTAL MAITYKUNTAL MAITY
15 min read

The web is no longer just about static pages. Today, users expect instant updates โ€” whether itโ€™s a chat app, stock price ticker, multiplayer game, or live notifications.

But how do we make this happen? How can the client (browser or mobile app) and server communicate in real time?

In this blog, weโ€™ll explore different approaches to real-time communication โ€” from traditional methods to modern solutions โ€” with examples and use cases for each.


๐ŸŸข 1. The Traditional Approach: HTTP Polling

Polling is the simplest way to get real-time-like behavior. The client repeatedly asks the server for new data at regular intervals.

๐Ÿ”น How It Works:

  1. The client sends an HTTP request every few seconds.
  2. The server responds with the latest data.
  3. The client updates the UI if thereโ€™s new information.

๐Ÿ”น Example (JavaScript):

setInterval(async () => {
  const response = await fetch('/messages');
  const messages = await response.json();
  console.log("Latest messages:", messages);
}, 3000); // every 3 seconds

โœ… Pros:

  • Very easy to implement.
  • Works with all browsers and servers.
  • No special protocols needed.

โŒ Cons:

  • Wastes resources (server gets requests even if nothing has changed).
  • Not truly "real-time" (depends on polling interval).
  • High latency for critical applications.

๐Ÿ”น Best Use Case:

  • When real-time isnโ€™t critical (e.g., checking for new blog comments).

๐ŸŸข 2. Long Polling

Long polling is an improvement over normal polling. Instead of responding immediately, the server holds the request open until new data is available.

๐Ÿ”น How It Works:

  1. The client sends a request to the server.
  2. The server waits until it has new data, then responds.
  3. Once the client receives a response, it sends another request immediately.

๐Ÿ”น Example (Node.js + Express):

// Server-side (Node.js + Express)
app.get('/updates', (req, res) => {
  setTimeout(() => {
    res.json({ message: "New data available!" });
  }, 5000); // simulate delay
});
// Client-side
async function getUpdates() {
  const response = await fetch('/updates');
  const data = await response.json();
  console.log(data);
  getUpdates(); // call again to keep listening
}
getUpdates();

โœ… Pros:

  • More efficient than regular polling.
  • Works without special protocols.

โŒ Cons:

  • Still uses HTTP for every message.
  • Not as efficient as WebSockets or Server-Sent Events.

๐Ÿ”น Best Use Case:

  • Notifications and updates where WebSockets are not available.

๐ŸŸข 3. Server-Sent Events (SSE)

Most beginners jump straight to WebSockets when thinking about real-time communication, but sometimes you donโ€™t need two-way communication. If your application only requires the server to push updates to the client (one-way), then Server-Sent Events (SSE) is often the simplest and most efficient choice.

๐Ÿ”น How It Works

SSE uses a long-lived HTTP connection (usually GET) where:

  1. Client opens a connection using the built-in EventSource API in JavaScript.

    • This is just like opening a normal HTTP request, but it stays open.
  2. Server keeps the connection alive and streams messages whenever thereโ€™s new data.

    • Instead of closing after one response, the server keeps writing data to the client.
  3. Client receives events in real-time.

    • Each event is sent in a special text-based format that starts with data:.
  4. Automatic reconnection.

    • If the connection drops (e.g., due to network issues), the browser automatically reconnects after a few seconds.
    • You donโ€™t have to write extra reconnection logic (which you need in WebSockets).

๐Ÿ”น Example

Letโ€™s build a real-time clock using SSE.

Client-Side (Browser)

// Open a connection to the server
const eventSource = new EventSource('/time');

// Default message handler
eventSource.onmessage = (event) => {
  console.log("Current time:", event.data);
  document.body.innerHTML = `<h1>${event.data}</h1>`;
};

// Optional: Listen to custom events
eventSource.addEventListener("news", (event) => {
  console.log("Breaking news:", event.data);
});

// Handle errors (auto-reconnect will still happen)
eventSource.onerror = () => {
  console.log("Connection lost, trying to reconnect...");
};

Server-Side (Node.js + Express)

const express = require('express');
const app = express();

app.get('/time', (req, res) => {
  // Tell the browser this is an event stream
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');

  // Send a message every second
  setInterval(() => {
    const now = new Date().toLocaleTimeString();
    res.write(`data: ${now}\n\n`);
  }, 1000);

  // Optional: Send a custom event
  setTimeout(() => {
    res.write("event: news\n");
    res.write("data: Server-Sent Events are awesome!\n\n");
  }, 5000);
});

app.listen(3000, () => console.log("SSE server running on http://localhost:3000"));

๐Ÿ”Ž Whatโ€™s Happening?

  • res.setHeader('Content-Type', 'text/event-stream') โ†’ tells the browser this is a continuous stream.
  • res.write("data: ...\n\n") โ†’ sends a message to the client (note the double \n\n which is required by the SSE spec).
  • On the client, eventSource.onmessage receives these messages automatically.
  • If the connection drops, the browser reconnects.

๐Ÿ”น Format of SSE Messages

Each message from the server follows this simple text format:

data: Hello, this is a message!

For custom events:

event: news
data: Breaking: Server-Sent Events are lightweight!

For multiple lines:

data: This is line 1
data: This is line 2

The browser automatically combines them into a single message.

โœ… Pros of SSE

  • Easy to implement: Just use EventSource in the browser โ€” no extra libraries.
  • Built-in automatic reconnection: Browser reconnects if the connection drops.
  • Lightweight protocol: Text-based, simple to debug, runs over plain HTTP.
  • Supports custom events: You can send different event types (news, update, etc.).
  • Better than Polling/Long Polling: No need to open and close connections repeatedly.
  • Firewall-friendly: Since it uses regular HTTP, it works well across firewalls and proxies.

โŒ Cons of SSE

  • One-way only: Server โ†’ Client.

    • If the client needs to send data, it must use a normal HTTP request or another channel.
  • No binary support: SSE sends only UTF-8 text, unlike WebSockets that can send binary data.
  • Limited browser support in the past: Modern browsers support SSE, but old versions of Internet Explorer donโ€™t.
  • Connection limits: Some browsers limit how many open SSE connections a single domain can have (e.g., 6).

๐Ÿ”น Best Use Cases for SSE

SSE is perfect when:

  • The server only needs to push updates (no need for full two-way communication).
  • You want simplicity over complex setups like WebSockets.
  • Applications like:

    • ๐Ÿ“Š Live dashboards (e.g., monitoring CPU usage, logs).
    • ๐Ÿ“ฐ Live news or stock tickers.
    • โšฝ Sports score updates.
    • ๐Ÿ”” Notifications/alerts.
    • โฐ Real-time clocks, timers, or status updates.

๐ŸŸข 4. WebSockets

When you need true real-time, two-way communication between the client and the server, WebSockets are the go-to solution.

Unlike Server-Sent Events (SSE), which only allow the server to push data to the client, WebSockets provide a bi-directional channel where both client and server can send and receive data anytime.

Thatโ€™s why WebSockets are used in chat apps, multiplayer games, live trading dashboards, and collaborative tools.

๐Ÿ”น How It Works

  1. Handshake (Upgrade Request)

    • Communication starts as a normal HTTP request.
    • The client asks the server to "upgrade" the connection to the WebSocket protocol.

    Example request headers:

    GET /chat HTTP/1.1
    Host: example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Sec-WebSocket-Version: 13
    
  2. Upgrade Response

    • The server responds confirming the upgrade.
    • At this point, the connection switches from HTTP โ†’ WebSocket protocol.
  3. Full-Duplex Communication

    • Once established, both client and server can send messages anytime, without re-establishing the connection.
    • Messages are sent in small, efficient frames (text or binary).
  4. Persistent Connection

    • The connection remains open until either client or server closes it.
    • Unlike polling or SSE, no repeated HTTP requests are needed.

๐Ÿ”น Example

Letโ€™s build a simple chat app using WebSockets.

Server-Side (Node.js + ws library)

const WebSocket = require('ws');

// Create a WebSocket server on port 8080
const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', ws => {
  console.log("Client connected!");

  // Listen for messages from the client
  ws.on('message', message => {
    console.log(`Received: ${message}`);

    // Echo message back to client
    ws.send(`You said: ${message}`);
  });

  // Send a welcome message
  ws.send("Welcome to the WebSocket server!");
});

Client-Side (Browser JavaScript)

// Create WebSocket connection
const socket = new WebSocket('ws://localhost:8080');

// Connection opened
socket.onopen = () => {
  console.log("Connected to server");
  socket.send("Hello Server!");
};

// Listen for messages
socket.onmessage = (event) => {
  console.log("Message from server:", event.data);
};

// Handle errors
socket.onerror = (error) => {
  console.error("WebSocket Error:", error);
};

// Handle connection close
socket.onclose = () => {
  console.log("Connection closed");
};

โœ… Now, whenever the client sends a message, the server instantly receives it and can respond back โ€” no polling required.

๐Ÿ”น WebSocket Message Format

WebSocket messages are sent in frames. Two main types:

  • Text frames โ†’ UTF-8 text messages.
  • Binary frames โ†’ Binary data (e.g., images, audio, video chunks).

This makes WebSockets ideal for applications that deal with more than just text.

โœ… Pros of WebSockets

  • Bi-directional: Both client and server can send/receive messages anytime.
  • Truly real-time: Near-zero latency after connection is established.
  • Efficient: Only one connection, no repeated HTTP requests.
  • Supports binary data: Unlike SSE, WebSockets can send images, audio, or binary blobs.
  • Widely supported: Works on all modern browsers and mobile apps.
  • Scalable: Can handle thousands of simultaneous connections with proper infrastructure.

โŒ Cons of WebSockets

  • More complex: Harder to implement than SSE or polling.
  • Needs stateful servers: Unlike stateless HTTP, servers must track connections.
  • Scaling challenges: Load balancing WebSockets requires special considerations.
  • No built-in reconnection: If a connection drops, you must write custom reconnection logic.
  • Not ideal for one-way feeds: SSE is simpler and more efficient if you only need server โ†’ client communication.

๐Ÿ”น Best Use Cases for WebSockets

WebSockets are the default choice when you need instant, two-way communication. Perfect for:

  • ๐Ÿ’ฌ Chat applications (WhatsApp Web, Slack, Discord).
  • ๐ŸŽฎ Multiplayer online games (real-time player updates).
  • ๐Ÿ“Š Live dashboards (stock prices, trading apps, monitoring tools).
  • โœ๏ธ Collaborative apps (Google Docs, whiteboards, shared coding).
  • ๐Ÿ“ก IoT device communication (devices streaming data to servers).

๐ŸŸข 5. WebRTC

When we talk about real-time communication, WebSockets and SSE usually come to mind. But thereโ€™s another powerful technology designed for direct peer-to-peer communication: WebRTC (Web Real-Time Communication).

Unlike WebSockets (which always go through a central server), WebRTC allows browsers, mobile apps, or devices to talk directly to each other for audio, video, and data sharing.

Thatโ€™s why WebRTC powers apps like Google Meet, Zoom (web client), Discord voice chat, and file-sharing tools.

๐Ÿ”น How It Works

WebRTC is more complex than SSE or WebSockets because it involves peer-to-peer connections. The process usually involves three main steps:

  1. Signaling

    • Before two peers can connect, they need to exchange information like:

      • Network details (IP, ports).
      • Media capabilities (video/audio formats).
    • This is done using a signaling server (often via WebSockets or HTTP).
  2. Connection Establishment

    • Once peers have exchanged info, WebRTC tries to connect directly using ICE (Interactive Connectivity Establishment).
    • It may use STUN servers (to discover public IP addresses behind NAT) or TURN servers (relay when direct connection isnโ€™t possible).
  3. Peer-to-Peer Communication

    • After setup, peers exchange video, audio, or data directly without sending everything through the main server.
    • This reduces latency and server costs.

๐Ÿ”น Example: Simple WebRTC Setup

Letโ€™s build a very basic example where two browsers exchange video streams.

Client-Side (Browser JavaScript)

// Create a peer connection
const peer = new RTCPeerConnection();

// Get access to webcam + microphone
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
  .then(stream => {
    // Show local video
    document.getElementById("localVideo").srcObject = stream;

    // Add tracks to peer connection
    stream.getTracks().forEach(track => peer.addTrack(track, stream));
  });

// Handle remote stream
peer.ontrack = (event) => {
  document.getElementById("remoteVideo").srcObject = event.streams[0];
};

// Create an offer (for signaling)
peer.createOffer().then(offer => {
  peer.setLocalDescription(offer);
  // Send this offer to the other peer via a signaling server
});

๐Ÿ”Ž Whatโ€™s happening here:

  • We request camera + microphone access.
  • We attach our media tracks to the peer connection.
  • We create an offer that contains connection details.
  • This offer must be sent to the other peer using a signaling channel (e.g., WebSocket server).

On the other peerโ€™s side, they would:

  • Receive the offer.
  • Set it as their remote description.
  • Generate an answer and send it back.

After this handshake, the peers are connected and can exchange video/audio directly.

๐Ÿ”น WebRTC Data Channels

Besides video and audio, WebRTC also supports data channels for sending text, JSON, or files peer-to-peer.

const peer = new RTCPeerConnection();

// Create a data channel
const channel = peer.createDataChannel("chat");

// When the connection is open, send a message
channel.onopen = () => {
  channel.send("Hello from Peer 1!");
};

// Listen for messages
channel.onmessage = (event) => {
  console.log("Received:", event.data);
};

โœ… This can be used for real-time gaming, file sharing, or even building a peer-to-peer chat app without a central server.

โœ… Pros of WebRTC

  • Peer-to-peer โ†’ Low latency, no central server for streaming.
  • Supports video, audio, and data โ†’ Perfect for conferencing and file sharing.
  • Bandwidth efficient โ†’ No need to relay everything through a central server.
  • Secure by default โ†’ Uses DTLS (Datagram Transport Layer Security) and SRTP (Secure Real-time Transport Protocol).
  • Cross-platform โ†’ Works in browsers, mobile apps, IoT devices.

โŒ Cons of WebRTC

  • Complex setup โ†’ Requires signaling, STUN/TURN servers, and handling NAT/firewall issues.
  • Not just client-server โ†’ Works best for peer-to-peer, but scaling to many users (like a Zoom call) often requires additional media servers (SFU/MCU).
  • Browser compatibility quirks โ†’ While widely supported, there can be differences in implementation.
  • Extra servers still needed โ†’ Even though media is P2P, you need signaling + TURN fallback servers.

๐Ÿ”น Best Use Cases for WebRTC

WebRTC is designed for real-time peer-to-peer interactions:

  • ๐ŸŽฅ Video conferencing apps (Google Meet, Jitsi, Zoom web client).
  • ๐ŸŽ™๏ธ Voice chat apps (Discord, WhatsApp Web calls).
  • ๐Ÿ“‚ Peer-to-peer file sharing (send files directly without uploading to a server).
  • ๐ŸŽฎ Multiplayer games (fast, low-latency data channels).
  • ๐Ÿš€ IoT communication (devices streaming live sensor/video data).

๐ŸŸข 6. Using Third-Party Services

Sometimes, setting up your own WebSockets, SSE, or WebRTC infrastructure can feel overwhelming โ€” especially if youโ€™re just starting out or want to move fast.

Thatโ€™s where third-party services and libraries come in. They handle the complex real-time logic, so you can focus on building your app.

Here, weโ€™ll look at two of the most popular options:


๐Ÿ”น Firebase Realtime Database / Firestore

Firebase (by Google) is a Backend-as-a-Service (BaaS) platform. Its Realtime Database and Cloud Firestore allow apps to sync data instantly across clients without you having to manage WebSockets or servers.

How It Works:

  • Data is stored in a NoSQL database (JSON for Realtime Database, document/collection model for Firestore).
  • When data changes, all connected clients automatically get updates in real time.
  • Firebase handles the underlying WebSockets/SSE for you.

Example (Firestore โ€“ Client Side)

import { initializeApp } from "firebase/app";
import { getFirestore, collection, onSnapshot } from "firebase/firestore";

const firebaseConfig = {
  apiKey: "your-api-key",
  authDomain: "your-app.firebaseapp.com",
  projectId: "your-project-id"
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);

// Listen to real-time updates
const messagesRef = collection(db, "messages");
onSnapshot(messagesRef, (snapshot) => {
  snapshot.docs.forEach(doc => {
    console.log("New message:", doc.data());
  });
});

โœ… In this example, whenever a new message is added to the messages collection, all connected clients immediately receive it.

Pros:

  • Super easy to set up (just client-side code).
  • No backend setup needed.
  • Scales automatically.
  • Great for beginners.

Cons:

  • Vendor lock-in (tied to Google Cloud).
  • Pricing can grow as usage scales.
  • Less flexible for advanced use cases compared to building your own backend.

Best Use Cases:

  • Simple chat apps.
  • Live feeds (news, comments, dashboards).
  • Collaborative tools with low-to-medium scale.

๐Ÿ”น Socket.IO (on top of WebSockets)

Socket.IO is a popular JavaScript library that makes working with WebSockets much easier. While WebSockets themselves are powerful, they can be tricky to implement (handling reconnections, fallbacks, etc.). Socket.IO abstracts all of that.

How It Works:

  • Socket.IO runs on top of WebSockets (and falls back to long-polling if needed).
  • Provides a simple event-based API (socket.emit, socket.on).
  • Handles automatic reconnection, fallback, and broadcasting out of the box.

Example

Server (Node.js + Express)

const express = require("express");
const http = require("http");
const { Server } = require("socket.io");

const app = express();
const server = http.createServer(app);
const io = new Server(server);

io.on("connection", (socket) => {
  console.log("A user connected");

  // Listen for messages from client
  socket.on("chat message", (msg) => {
    console.log("Message:", msg);
    // Broadcast to all clients
    io.emit("chat message", msg);
  });

  socket.on("disconnect", () => {
    console.log("User disconnected");
  });
});

server.listen(3000, () => {
  console.log("Socket.IO server running on http://localhost:3000");
});

Client (Browser)

const socket = io("http://localhost:3000");

// Send a message
socket.emit("chat message", "Hello everyone!");

// Listen for messages
socket.on("chat message", (msg) => {
  console.log("Received:", msg);
});

โœ… With just a few lines, you get a real-time chat system with broadcasting and reconnection handling.

Pros:

  • Event-driven API (easy to reason about).
  • Handles reconnections and fallbacks automatically.
  • Supports rooms and namespaces (for scaling).
  • Works well for chat apps, multiplayer games, live dashboards.

Cons:

  • Requires setting up a backend server (unlike Firebase).
  • Adds an abstraction layer over WebSockets, which may limit very advanced use cases.

Best Use Cases:

  • Chat/messaging apps.
  • Multiplayer games.
  • Collaboration tools (whiteboards, shared docs).
  • Apps where you want full control of the backend.

๐Ÿ† Which One Should You Choose?

MethodDirectionEfficiencyBest For
PollingClient โ†’ ServerโŒ PoorSimple checks
Long PollingClient โ†” Serverโšก BetterNotifications
SSEServer โ†’ Clientโšก EfficientFeeds, tickers
WebSocketsClient โ†” Server๐Ÿš€ ExcellentChat, games, dashboards
WebRTCPeer โ†” Peer๐Ÿš€ ExcellentVideo/voice apps
Third-PartyVariesโœ… Easy setupQuick prototypes, scaling

๐ŸŽฏ Conclusion

Real-time communication is essential in modern apps.

  • Use Polling/Long Polling if simplicity matters.
  • Use SSE if updates are one-way.
  • Use WebSockets for full bi-directional communication.
  • Use WebRTC for peer-to-peer video/audio.
  • Use third-party services for faster development.

๐Ÿ‘‰ The right choice depends on your use case, scale, and complexity.


โœจ Thatโ€™s it! Now you know the different ways to implement real-time communication. Which one have you used in your projects? Let me know in the comments! ๐Ÿš€


๐Ÿ”— Whatโ€™s Next?

You might want to explore:

โœ๏ธ Authorโ€™s Note

This blog is a comprehensive guide to real-time communication methods, but the best way to learn is by doing! Try implementing these techniques in your own projects. If you have any questions or suggestions, feel free to reach out.


๐Ÿ’ฌ Have Questions or Suggestions?

Drop a comment below or connect with me on LinkedIn or GitHub. Letโ€™s make apps faster together! ๐Ÿš€

0
Subscribe to my newsletter

Read articles from KUNTAL MAITY directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

KUNTAL MAITY
KUNTAL MAITY

Iโ€™m a passionate Full-Stack Developer who loves building performance-driven web and mobile applications. I work primarily with JavaScript, React, Next.js, Node.js, and MongoDB, and I enjoy simplifying complex concepts into developer-friendly tutorials. On this blog, you'll find hands-on guides, real-world projects, and developer insightsโ€”all aimed at helping you level up your coding skills and build production-ready apps. Whether you're into backend performance, frontend polish, or full-stack architecture, there's something here for you! Letโ€™s learn, build, and grow together. ๐Ÿ’ปโœจ