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.
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-aliveDemo 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.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.