Frontend Development 16 min read

Enterprise-Level Server-Sent Events (SSE) Implementation for Ctrip Flight Frontend

This article presents Ctrip's enterprise-grade Server-Sent Events (SSE) solution for its flight booking frontend, detailing the technology overview, use cases, implementation practices, performance considerations, comparison with alternatives, and full‑stack integration across link, framework, and data layers.

Ctrip Technology
Ctrip Technology
Ctrip Technology
Enterprise-Level Server-Sent Events (SSE) Implementation for Ctrip Flight Frontend

In modern web applications, real‑time data push is essential for many business scenarios. Ctrip's flight booking platform faces high‑frequency, multi‑dimensional flight data requirements, making Server‑Sent Events (SSE) a suitable solution for server‑initiated push and client‑side real‑time display.

SSE is a one‑way HTTP long‑connection technology that streams events from server to client. The client opens a persistent connection via EventSource , and the server sends a stream of events, each containing an id, event type, data, and optional retry interval.

Typical SSE use cases include live data streams (stock updates, news, sports scores), real‑time notifications (social messages, new orders), and dashboard updates (system monitoring, statistics).

Ctrip applied SSE to the flight list page, replacing multiple serial requests with a single persistent connection that pushes batches of flight data. This reduced request complexity, eliminated the need for Redis caching of pre‑fetched batches, and simplified client logic.

Before SSE, the client had to issue two requests: the first fetched the initial batch, while the server pre‑fetched the second batch into Redis to speed up the second request. After SSE, a single request streams all data, and the entire link operates in a flow‑based manner.

Benefits of SSE include reduced transmission latency (fewer requests), cleaner front‑end code, simplified service logic (no Redis pub/sub), and higher resource utilization.

Performance analysis shows that SSE’s main advantage is request‑count reduction; actual latency gains depend on whether server processing time exceeds network transmission time.

Comparing push technologies (SSE, polling, WebSocket), SSE was chosen for its simplicity, lightweight protocol, and browser compatibility, especially for server‑driven data scenarios.

SSE messages consist of four fields: event , data , id , and retry . Each message ends with a double newline ("\n\n").

Front‑end usage example:

// Create EventSource
const evtSource = new EventSource("API_ENDPOINT");

// Listen for messages
evtSource.onmessage = function (event) {
  console.log("Received message:", event);
};

// Connection opened
evtSource.onopen = function () {
  console.log("Connection opened");
};

// Error handling
evtSource.onerror = function (err) {
  console.error("Error occurred:", err);
};

Node.js server‑side example:

const http = require("http");
http.createServer((req, res) => {
  res.writeHead(200, {
    "Content-Type": "text/event-stream",
    "Cache-Control": "no-cache",
    Connection: "keep-alive",
  });
  const pushData = setInterval(() => {
    res.write(data);
  }, 1000);
  req.on("close", () => clearInterval(pushData));
}).listen(3000);

Two internal SSE solutions were evaluated: a custom responsive gateway that polls upstream services and a front‑end‑downstream BFF that maintains an SSE channel to the gateway. Neither provided full‑stack flow, so a collaborative effort among the Ctrip framework team, SRE, and front‑ and back‑end teams produced a company‑wide, universally applicable SSE solution.

Technical selection compared native SSE with Microsoft’s @microsoft/fetch-event-source (fes). Native SSE only supports GET requests and cannot set custom headers, limiting authentication scenarios. fes, built on Fetch and ReadableStream, overcomes these limitations and offers finer‑grained control.

Key fes functions include getBytes (reads byte chunks), getLines (parses lines), and getMessages (assembles EventSourceMessage objects). Performance tests showed negligible latency differences between native SSE and fes.

Full‑link support required adaptations at the link, framework, and data layers. In multi‑region, multi‑layer network environments, headers like X-Accel-Buffering: no were added to disable Nginx buffering, and proxy settings ensured header propagation across layers.

Framework integration wrapped fes into Ctrip’s base network library, while the back‑end used Reactor + Dubbo Streaming for reactive, flow‑based inter‑service communication.

Data‑layer considerations involved configuring servers (Nginx, Tomcat) to correctly handle the text/event-stream MIME type without compression, preventing unnecessary payload growth.

In conclusion, the article outlines Ctrip’s end‑to‑end SSE practice for flight booking, achieving real‑time server push, reduced code complexity, and improved resource utilization, while providing a reusable pattern for future streaming scenarios.

Frontendperformancereal-timeNode.jsServer-Sent EventsSSEEventSource
Ctrip Technology
Written by

Ctrip Technology

Official Ctrip Technology account, sharing and discussing growth.

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.