Is WebSocket Still the Best Choice for Real‑Time Push? Exploring SSE as a Lighter Alternative

The article compares polling, WebSocket, and Server‑Sent Events for server‑to‑client push, explains why polling is inefficient, outlines the advantages and browser compatibility of WebSocket and SSE, and provides step‑by‑step Node/Express and plain‑HTML demos showing how to implement SSE in practice.

macrozheng
macrozheng
macrozheng
Is WebSocket Still the Best Choice for Real‑Time Push? Exploring SSE as a Lighter Alternative

Introduction

In many everyday development scenarios—such as real‑time dashboards, unread‑message notifications, or chat features—the server needs to push data to the client proactively. This article introduces Server‑Sent Events (SSE), compares it with WebSocket and traditional polling, and shows how to implement SSE with a simple Node.js/Express backend and a plain HTML frontend.

Implementation Options for Server‑to‑Client Push

Polling

WebSocket

SSE

Polling Overview

Polling creates the illusion of push by repeatedly sending HTTP requests from the client. It is considered the least desirable method because each request incurs the full HTTP handshake, consumes client resources continuously, and is limited by the browser's concurrent request cap (e.g., Chrome allows only six simultaneous connections per domain). Long‑running polls also suffer from delayed data delivery.

WebSocket Overview

WebSocket is a full‑duplex protocol (ws/wss) that enables bidirectional communication between client and server. Its strengths are powerful features and support for real‑time two‑way messaging, but it requires server‑side support for the new protocol and may have compatibility issues in older browsers.

SSE Overview

SSE is a one‑way, long‑living HTTP/1.1 connection that allows the server to push events to the browser. It is lightweight, uses the existing HTTP infrastructure, and therefore enjoys broader server support without extra configuration. However, Internet Explorer does not support SSE, and mini‑programs (e.g., WeChat) also lack support.

WebSocket vs. SSE Comparison

WebSocket: full‑duplex, stronger functionality, requires ws protocol support.

SSE: one‑way, lightweight, built on HTTP, easier to deploy.

Both provide decent browser compatibility; SSE automatically reconnects on disconnection, while WebSocket needs additional handling.

SSE supports custom data types and is less complex to implement.

SSE API Details

Creating an SSE connection in JavaScript: var source = new EventSource(url); Connection readyState values:

0 – CONNECTING (connection not yet established or disconnected)

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

2 – CLOSED (connection closed and will not reconnect)

Key SSE events:

open – triggered when the connection opens.

message – triggered when data arrives.

error – triggered on communication errors, such as disconnection.

Typical response headers for an SSE stream:

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

Demo: Frontend 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>SSE Demo</title>
</head>
<body>
  <ul id="ul"></ul>
  <script>
    // Generate list item
    function createLi(data) {
      let li = document.createElement("li");
      li.innerHTML = String(data.message);
      return li;
    }
    // Check browser 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>

Demo: Backend Code (Node + Express)

const express = require('express');
const app = express();
const port = 8088;
// 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',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive'
  });
  console.log("Entered long‑connection");
  setInterval(() => {
    const data = { message: `Current time is ${new Date().toLocaleTimeString()}` };
    res.write(`data: ${JSON.stringify(data)}

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

Result

Running the demo shows a continuously updating list of timestamps on the page, confirming that the SSE connection successfully pushes data from the server to the client.

Conclusion

SSE is lighter than WebSocket.

SSE runs over standard HTTP/HTTPS.

WebSocket introduces a new ws/wss protocol.

For one‑way server‑to‑client pushes, SSE is the recommended choice.

For bidirectional communication (e.g., chat), WebSocket is more suitable.

Both protocols have good browser compatibility, except IE does not support SSE.

Polling should be avoided due to high client resource consumption, though it can be a quick fallback.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Node.jsWebSocketExpressReal‑time communicationServer‑Sent EventsPollingSSE
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

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.