1
0
Files
spring-messaging-demo/sse-websocket/docs/01-two-protocols.md
2026-09-04 00:52:18 +05:30

82 lines
4.1 KiB
Markdown

# 1. Two protocols, one question
Next: [2. The SSE lifecycle](02-sse-lifecycle.md)
---
Server-Sent Events and WebSocket get compared as if they were rivals for the same job. They are
not. The question that separates them is much smaller than "which is better", and it is this:
> **Does the client need to send anything after the first request?**
If the answer is no — a dashboard, a progress bar, a notification feed, a log tail, a
"your export is ready" ping — SSE is the whole answer, and it is a return type rather than a
subsystem. If the answer is yes, and the messages are frequent or need routing between clients,
you want WebSocket, and almost certainly STOMP on top of it.
Everything else in the comparison follows from that one asymmetry.
## What each one costs you to set up
| | SSE | STOMP over WebSocket |
|---|---|---|
| Dependency | `spring-boot-starter-webmvc` | `spring-boot-starter-websocket` |
| Auto-configuration involved | none | `spring-boot-websocket` |
| Server-side surface | a handler method returning `SseEmitter` | `@EnableWebSocketMessageBroker`, a configurer, a broker, a converter stack |
| Transport | one long-lived HTTP response | an HTTP/1.1 Upgrade to a framed, bidirectional connection |
| Client | `new EventSource(url)`, built into every browser | a STOMP library |
| Reconnect | automatic, with `Last-Event-ID` | yours to write |
| Server knows who is connected | no | yes — `SimpUserRegistry`, connect/subscribe/disconnect events |
| Payload | UTF-8 text only | text or binary |
The dependency line is the Boot 4 detail worth stating out loud. `spring-boot-starter-websocket`
pulls in `spring-boot-websocket`, which is where the auto-configuration lives. Depending on
`org.springframework:spring-websocket` and `spring-messaging` directly compiles and starts, and
then nothing works — the same rule that catches people with `spring-kafka` in
[`../kafka-basics`](../kafka-basics/README.md) and `spring-rabbit` in
[`../rabbitmq`](../rabbitmq/README.md). In Boot 4, **depending on a library rather than on its
Boot starter means you are missing its auto-configuration.**
## What SSE is not
Two things people assume, both wrong, both measured in this module:
**"It pins a thread per client."** It does not. `SseEmitter` switches the request to asynchronous
mode; the request thread goes back to the pool immediately and the response stays open with
nothing attached to it. [`SseConcurrencyTest`](../src/test/java/com/ankurm/ssews/SseConcurrencyTest.java)
holds forty streams open against a connector whose pool is capped at ten:
```
emitters open : 40
connector pool size : 10 (max 10)
connector active : 0
```
**"You have to pass a media type or it calls `toString()`."** Also not true, and the opposite is
closer to it. See [3. The payload](03-the-payload.md).
## What SSE genuinely cannot do
- **Take input.** `EventSource` issues one GET and never sends again. Client-to-server traffic has
to go over ordinary HTTP requests, which is fine for low rates and awful for a chat.
- **Send custom headers.** The browser's `EventSource` has no header API, so bearer-token
authentication needs a cookie or a query parameter. `withCredentials` exists; `Authorization`
does not.
- **Carry binary.** The format is line-oriented UTF-8. Binary means base64, which costs a third.
- **Tell you a client left.** There is no disconnect event, only a write that fails later —
see [2. The SSE lifecycle](02-sse-lifecycle.md).
- **Escape the browser's per-origin connection limit.** Over HTTP/1.1 a browser allows about six
concurrent connections to one origin, and an open SSE stream is one of them, *per tab*. Four
tabs of a dashboard is 4 streams; six is a hung site. HTTP/2 multiplexes and the limit
effectively disappears, which makes "do we serve this over HTTP/2?" a real part of the decision.
## What STOMP costs
A broker, a message-converter stack, a session registry, an origin policy, and a set of routing
rules whose defaults are not what you would guess. Chapters
[4](04-stomp.md) and [5](05-limits.md) are that list.
---
Next: [2. The SSE lifecycle](02-sse-lifecycle.md)