Why ChatGPT Uses Server-Sent Events (SSE) and How to Implement SSE in Spring Boot
This article explains why ChatGPT adopts Server-Sent Events for streaming responses, compares SSE with WebSocket, outlines SSE's core principles and best‑practice considerations, and provides a complete Spring Boot example—including server‑side Java code and client‑side HTML—to demonstrate real‑time data push.
Why ChatGPT Uses SSE
When exploring ChatGPT’s usage, we discovered that it returns data using a streaming approach. Although a persistent full‑duplex connection could be used, ChatGPT opts for Server‑Sent Events (SSE), which fits the scenario where large language model responses may take a long time and need incremental delivery to keep the user’s page open.
What Is SSE?
SSE (Server‑Sent Events) is a web technology that allows a server to push data to a client over a single, long‑lived HTTP connection. It is defined in the HTML5 specification and uses the EventSource API on the browser side. Data is sent as plain text (often JSON) with the MIME type text/event-stream.
Simple to use – text‑based format.
Unidirectional – server‑to‑client only.
Real‑time – the server can push updates without the client polling.
SSE vs. WebSocket
Direction: SSE is one‑way (server → client); WebSocket supports full duplex.
Connection establishment: SSE uses a regular HTTP GET request; WebSocket upgrades the connection with a custom protocol.
Compatibility: SSE works on any modern browser without extra handshakes; WebSocket is widely supported but may encounter restrictions in some network environments.
Use cases: SSE suits scenarios like live stock quotes or news feeds; WebSocket is better for chat, collaborative editing, or any bidirectional interaction.
How SSE Works
Client sends an HTTP GET request to the SSE endpoint.
Server responds with status 200 and Content‑Type: text/event-stream.
Server pushes events, each consisting of lines such as data:, id:, or event:, separated by a double newline.
Browser receives events via the EventSource object and triggers JavaScript handlers.
If the connection drops, the client automatically reconnects, optionally sending the last received event ID via the Last‑Event‑ID header.
Practical Considerations When Using SSE
Asynchronous handling: Use async processing (e.g., Spring’s @Async or CompletableFuture) to avoid blocking server threads.
Timeout management: Set appropriate timeouts on SseEmitter and handle onTimeout to free resources.
Error handling: Use SseEmitter.completeWithError() on the server and eventSource.onerror on the client.
Memory management: Release SseEmitter instances promptly after disconnection to prevent leaks.
Concurrency: For many simultaneous connections, employ thread pools or reactive approaches to keep resource usage low.
Client compatibility: Verify that target browsers support SSE; provide a fallback (e.g., long polling) for older browsers.
Spring Boot SSE Example
Below is a minimal Spring Boot controller that streams random stock prices to the client.
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.util.Random;
@RestController
public class StockController {
@GetMapping(value = "/stock-price", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter streamStockPrice() {
SseEmitter emitter = new SseEmitter();
Random random = new Random();
new Thread(() -> {
try {
while (true) {
double price = 100 + random.nextDouble() * 10;
String message = String.format("%.2f", price);
emitter.send(SseEmitter.event().data(message));
Thread.sleep(1000);
}
} catch (Exception e) {
emitter.completeWithError(e);
}
}).start();
return emitter;
}
}The controller maps /stock-price to a method that returns an SseEmitter. A background thread generates a random price every second and pushes it to the client.
Client‑Side HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Real‑Time Stock Price</title>
</head>
<body>
<h1>Real‑Time Stock Price</h1>
<div id="stock-price"></div>
<script>
const eventSource = new EventSource('/stock-price');
eventSource.onmessage = function(event) {
document.getElementById('stock-price').innerHTML = event.data;
};
</script>
</body>
</html>The browser creates an EventSource pointing to /stock-price. Each incoming message updates the displayed price, demonstrating a complete end‑to‑end SSE solution.
Key Takeaways
SSE is a lightweight, HTTP‑based push technology that excels in scenarios requiring server‑to‑client streaming, such as live dashboards or notifications. It offers automatic reconnection and simple text‑based messages but cannot handle bidirectional communication, has connection‑count limits, and only supports GET requests. For truly interactive or high‑throughput use cases, WebSocket may be more appropriate, while SSE remains an excellent choice for lightweight, one‑way updates.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
ITPUB
Official ITPUB account sharing technical insights, community news, and exciting events.
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.
