Backend Development 12 min read

Server‑Sent Events (SSE) vs WebSocket vs Polling: Concepts, Comparison, and Implementation Demo

This article explains the three common server‑to‑client data push methods—polling, WebSocket, and SSE—detailing their principles, advantages, disadvantages, suitable business scenarios, and provides step‑by‑step Node.js/Express and plain JavaScript demos for implementing SSE.

Architecture Digest
Architecture Digest
Architecture Digest
Server‑Sent Events (SSE) vs WebSocket vs Polling: Concepts, Comparison, and Implementation Demo

In many web applications, the server needs to push data to the client in real time, such as dashboards, message centers, or chat functions. The three conventional solutions are polling, WebSocket, and Server‑Sent Events (SSE).

Polling

Polling is a pseudo‑push technique where the client repeatedly sends HTTP requests to the server. Its drawbacks include unnecessary connection overhead, continuous client resource consumption, limited browser concurrency (e.g., Chrome allows only six concurrent connections per host), and delayed data delivery.

WebSocket

WebSocket is a full‑duplex protocol that enables bidirectional communication between client and server. It offers powerful features but requires a new protocol (ws/wss) and server‑side support, making it heavier and less universally compatible than SSE.

Server‑Sent Events (SSE)

SSE is a lightweight, unidirectional protocol built on top of HTTP/1.1 long‑living connections. It allows the server to push data to the browser without additional server configuration, consumes fewer client resources, and automatically handles reconnection. However, it is not supported by older IE browsers and cannot be used in mini‑programs.

Comparison

WebSocket provides full‑duplex communication; SSE provides only server‑to‑client push.

WebSocket requires server support for the ws protocol; SSE works with any standard HTTP server.

SSE is simpler and lighter; WebSocket is more complex.

SSE includes built‑in reconnection logic; WebSocket needs custom handling.

SSE can send custom data types.

Typical use cases: SSE is ideal for real‑time dashboards and notification feeds that only need server‑to‑client updates, while WebSocket is suited for chat applications or any scenario requiring bidirectional messaging.

SSE Core API

var source = new EventSource(url);

Connection states (source.readyState): 0 = CONNECTING, 1 = OPEN, 2 = CLOSED.

Key events:

open – triggered when the connection is established.

message – triggered when data arrives.

error – triggered on communication errors.

Data format (HTTP headers):

Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

Demo Implementation

Frontend (plain HTML/JavaScript)

<!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>
function createLi(data) {
let li = document.createElement("li");
li.innerHTML = String(data.message);
return li;
}
let source = '';
if (window.EventSource) {
source = new EventSource('http://localhost:8088/sse/');
} else {
throw new Error("当前浏览器不支持SSE");
}
source.onopen = function(event) { console.log("长连接打开"); };
source.onmessage = function(event) {
const data = JSON.parse(event.data);
const li = createLi(data);
document.getElementById("ul").appendChild(li);
};
source.onerror = function(event) { console.log("长连接中断"); };
</script>
</body>
</html>

Backend (Node.js + Express)

const express = require('express');
const app = express();
const port = 8088;
// Enable CORS
app.all("*", (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',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
console.log('进入到长连接了');
setInterval(() => {
const data = { message: `Current time is ${new Date().toLocaleTimeString()}` };
res.write(`data: ${JSON.stringify(data)}\n\n`);
}, 1000);
});
app.listen(port, () => { console.log(`项目启动成功 - http://localhost:${port}`); });

Running the two files launches an SSE server that pushes the current time every second, and the browser displays each message as a list item.

Conclusion

SSE is lighter than WebSocket and works over standard HTTP.

Use SSE when only the server needs to push data.

Choose WebSocket for bidirectional communication such as chat.

Polling should be avoided due to high resource consumption.

IE does not support SSE; mini‑programs also lack SSE support.

JavaScriptNode.jsWebSocketExpressReal-time CommunicationpollingSSE
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

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.