# `Arc.Plug.SseHub`
[🔗](https://github.com/Cratis/Arc.Elixir/blob/main/lib/arc/plug/sse_hub.ex#L4)

The multiplexed Server-Sent Events hub at `/.cratis/queries/sse`.

It carries the same protocol as the WebSocket hub (`Arc.Plug.Hub`), for clients that cannot or
do not want a WebSocket. A browser `EventSource` can only receive, so the two directions use
two requests:

  * `GET /.cratis/queries/sse` opens the stream. It starts with a `Connected` message whose
    `payload` is the connection id, and carries every `QueryResult`, `Unauthorized`, `Error` and
    keep-alive `Ping` message as a `data:` event.
  * `POST /.cratis/queries/sse/subscribe` with `{connectionId, queryId, revision, request}` adds
    or revision-replaces a subscription on the stream.
  * `POST /.cratis/queries/sse/unsubscribe` with `{connectionId, queryId, revision}` cancels one.

Closing the stream ends every subscription it owns. A control request for an unknown connection,
or from a caller other than the one that opened the stream, is answered `404` (the same status
for both, so a connection id is never confirmed to someone else). The caller is compared on the
principal id and whether it is authenticated; the tenant is not compared, and each subscription
runs with the context of the POST that created it, so a client that sets the tenant header on
its control requests subscribes in that tenant. A connection opened by an anonymous caller has
no identity to bind to.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
