Backend Development 15 min read

Understanding Server‑Sent Events (SSE): Concepts, Comparison with Polling/WebSocket, and Practical Demo

This article explains the use cases and implementation of Server‑Sent Events (SSE), compares it with polling and WebSocket, details its API and browser compatibility, and provides complete front‑end and Node‑Express back‑end demo code for building a real‑time push service.

Top Architect
Top Architect
Top Architect
Understanding Server‑Sent Events (SSE): Concepts, Comparison with Polling/WebSocket, and Practical Demo

In many development scenarios the server needs to push data to the client in real time, such as live dashboards, unread message notifications, or chat features.

The article introduces three common solutions for server‑to‑client data push: polling, WebSocket, and SSE.

Polling Overview

Polling is a pseudo‑push technique where the client repeatedly sends HTTP requests to the server, creating unnecessary connection overhead, consuming browser concurrency slots, and often delivering data with latency.

WebSocket Overview

WebSocket provides a full‑duplex communication channel, allowing both client and server to send messages independently. It is powerful but requires the ws/wss protocol support on both ends, making it heavier than SSE.

SSE Overview

SSE is a one‑way, long‑living HTTP/HTTPS connection that lets the server push events to the browser. It is lightweight, uses the existing HTTP infrastructure, and enjoys good browser support (except IE).

Long connections are a persistent HTTP/1.1 feature that reduces the overhead of establishing new TCP connections for each request.

SSE advantages include lower complexity, less client resource consumption, and no need for additional server configuration beyond standard HTTP headers.

Differences Between WebSocket and SSE

WebSocket is full‑duplex; SSE is server‑to‑client only.

WebSocket requires a new protocol (ws/wss); SSE works over standard HTTP.

SSE is lighter and simpler; WebSocket is more feature‑rich but heavier.

SSE automatically reconnects on disconnection; WebSocket needs extra handling.

SSE allows custom data types.

Typical scenarios: use SSE for one‑way push such as live dashboards or notification centers; use WebSocket when bidirectional communication (e.g., chat) is required.

SSE Main API

Creating an SSE connection in JavaScript:

var source = new EventSource(url);

Connection readyState values:

EventSource.CONNECTING (0) – connection not yet established or reconnecting.

EventSource.OPEN (1) – connection open and receiving data.

EventSource.CLOSED (2) – connection closed and will not reconnect.

Key events:

open – triggered when the connection is opened.

message – triggered when a message is received.

error – triggered on communication errors.

Data Format

Content-Type: text/event-stream // response format
Cache-Control: no-cache      // prevent caching
Connection: keep-alive        // keep the long connection

Practical Demo

The front‑end demo is a plain HTML page that creates an EventSource , checks browser support, and appends received messages to a list:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>SSE Demo</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.readyState);
      console.log("长连接打开");
    };
    source.onmessage = function(event) {
      console.log(JSON.parse(event.data));
      console.log("收到长连接信息");
      let li = createLi(JSON.parse(event.data));
      document.getElementById("ul").appendChild(li);
    };
    source.onerror = function(event) {
      console.log(source.readyState);
      console.log("长连接中断");
    };
  </script>
</body>
</html>

The back‑end demo uses Node.js with Express to expose an /sse endpoint that sets the proper headers and sends a JSON payload every second:

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

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 a simple SSE service that streams the current time to the browser, demonstrating the lightweight nature of SSE compared to WebSocket.

Conclusion

SSE is lighter than WebSocket and works over standard HTTP.

Use SSE when only server‑to‑client push is needed (e.g., dashboards, notifications).

Choose WebSocket for bidirectional communication (e.g., chat).

Polling should be a last resort due to high resource consumption.

Note that IE does not support SSE and mini‑programs also lack SSE support.

backendfrontendNode.jsWebSocketExpressServer-Sent EventspollingSSE
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

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.