Backend Development 13 min read

Server‑to‑Client Data Push: SSE, WebSocket, and Polling – Concepts, Comparison, and Demo

This article explains the three common server‑to‑client push techniques—polling, WebSocket, and Server‑Sent Events (SSE)—detailing their principles, advantages, drawbacks, browser compatibility, appropriate use‑cases, and provides a complete Node.js/Express demo with front‑end code.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Server‑to‑Client Data Push: SSE, WebSocket, and Polling – Concepts, Comparison, and Demo

In many web applications, the server needs to push data to the client in real time, such as dashboards, message centers, or chat features. This article introduces the usage scenarios of Server‑Sent Events (SSE) and explains how to use SSE.

Implementation Schemes for Server‑to‑Client Data Push

The three conventional solutions are:

Polling

WebSocket

SSE

Polling Overview

Polling is a pseudo‑push technique where the client repeatedly sends HTTP requests to the server, creating the illusion of server‑initiated data delivery. It is the least efficient method because each request incurs the full HTTP handshake and consumes a browser connection slot.

Each request requires a new HTTP connection (handshake, teardown), causing unnecessary overhead.

The client must keep sending requests for the entire page lifetime, which is unfriendly to resources.

Browsers limit concurrent connections per host (e.g., Chrome allows only 6), and long‑running polls occupy these slots.

Long polling may not deliver data promptly.

WebSocket Overview

WebSocket is a full‑duplex protocol that enables bidirectional communication between client and server. It offers powerful features but requires browsers to support the ws/wss protocol, and the server must provide explicit support.

SSE Overview

SSE (Server‑Sent Events) is a unidirectional protocol built on a persistent HTTP/1.1 connection. The server can push data to the client, but the client cannot send messages back over the same channel.

Advantages of SSE include lightweight nature, lower client consumption, and reliance on standard HTTP, so existing servers support it without extra configuration. However, Internet Explorer does not support SSE.

Differences Between WebSocket and SSE

Polling

Polling is used only when both WebSocket and SSE are unavailable, serving as a fallback.

WebSocket vs. SSE

WebSocket provides full‑duplex communication; SSE is one‑way (server‑to‑client).

WebSocket requires server support for the ws protocol; SSE works over HTTP and is universally supported.

SSE is lightweight and simple; WebSocket is heavier and more complex.

SSE includes automatic reconnection; WebSocket needs additional handling.

SSE allows custom data types.

Business Scenarios

SSE is ideal for scenarios that only need server‑to‑client push, such as real‑time dashboards or notification centers. WebSocket is preferred for bidirectional communication, like chat applications.

SSE Core API

Creating an SSE connection:

var source = new EventSource(url);

Connection state:

source.readyState

0 – CONNECTING (connection not yet established or disconnected)

1 – OPEN (connection established, data can be received)

2 – CLOSED (connection closed, no reconnection)

SSE events:

open – triggered when the connection opens

message – triggered when data arrives

error – triggered on communication errors

Data format (HTTP headers):

Content-Type: text/event-stream // response format
Cache-Control: no-cache          // do not cache
Connection: keep-alive          // keep‑alive long connection

Demo: How to Implement an SSE Link

The front‑end uses a plain HTML page without any framework. The back‑end uses Node.js with Express.

Steps:

Create index.html with the front‑end demo code and open it in a browser.

Create index.js with the back‑end demo code, then run the following commands in its folder:

npm init          // initialize npm
npm i express     // install Express
node index        // start the server

Front‑end Demo Code

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <ul id="ul"></ul>
<script>
// generate li element
function createLi(data) {
  let li = document.createElement("li");
  li.innerHTML = String(data.message);
  return li;
}
// check SSE support
let source = '';
if (!!window.EventSource) {
  source = new EventSource('http://localhost:8088/sse/');
} else {
  throw new Error("Current browser does not support SSE");
}
// connection opened
source.onopen = function(event) {
  console.log(source.readyState);
  console.log("Long connection opened");
};
// message received
source.onmessage = function(event) {
  console.log(JSON.parse(event.data));
  console.log("Received long‑connection data");
  let li = createLi(JSON.parse(event.data));
  document.getElementById("ul").appendChild(li);
};
// connection error
source.onerror = function(event) {
  console.log(source.readyState);
  console.log("Long connection interrupted");
};
</script>
</body>
</html>

Back‑end Demo Code (Node.js + Express)

const express = require('express'); // import framework
const app = express();
const port = 8088; // server port

// enable CORS
app.all("*", function(req, res, next) {
  res.header("Access-Control-Allow-Origin", '*');
  res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
  res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
  res.header("Access-Control-Allow-Credentials", true);
  if (req.method == 'OPTIONS') {
    res.sendStatus(200);
  } else {
    next();
  }
});

app.get("/sse", (req, res) => {
  res.set({
    'Content-Type': 'text/event-stream', // data type
    'Cache-Control': 'no-cache',        // no cache for long connection
    'Connection': 'keep-alive'         // keep‑alive
  });
  console.log("Entered long connection");
  setInterval(() => {
    console.log("Sending data continuously");
    const data = {
      message: `Current time is ${new Date().toLocaleTimeString()}`
    };
    res.write(`data: ${JSON.stringify(data)}\n\n`);
  }, 1000);
});

// start server
app.listen(port, () => {
  console.log(`Server started – http://localhost:${port}`);
});

Conclusion

SSE is lighter than WebSocket.

SSE is based on HTTP/HTTPS.

WebSocket uses a new ws/wss protocol.

Use SSE when only server‑to‑client push is needed.

Choose WebSocket for bidirectional communication.

Both SSE and WebSocket have good browser compatibility (except IE for SSE).

Polling is a last‑resort method and consumes client resources.

Mini‑programs do not support SSE.

frontendreal-timeNode.jsWebSocketExpresspollingSSE
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.