Search code examples
httpserver-sent-events

Why and how SSE (Server-Sent Events) are unidirectional


https://developer.mozilla.org/en-US/docs/Web/API/EventSource

The EventSource interface is web content's interface to server-sent events. An EventSource instance opens a persistent connection to an HTTP server, which sends events in text/event-stream format. The connection remains open until closed by calling EventSource.close().

From what I understand server-sent events require persistent HTTP connection (Connection: keep-alive) so similarly to keeping the connection alive like in case of web sockets.

If the connection is persistent, why server-sent events are unidirectional? Web socket connections are persistent as well.

In this case, what happens if I send a request to my HTTP service and I have persistent connection opened due to EventSource. Will it re-use HTTP connection opened by EventSource or open a new connection?

If it re-uses the connection opened by EventSource how is it considered unidirectional?

Might be trivial, but I had to ask because it is not clear. Because nothing mentions what happens to subsequent HTTP requests when there's existing connection opened by EventSource.

For example, it seems possible to me to implement centralized chat app using SSE:

User 1 sends message to User 2(by sending it to HTTP server). Server sends event to user 2 with a new message, user 2 sends another request to HTTP server with message for User 1, server sends event to user 1.

How is that not considered bi-directional?

Related:

What's the behavioral difference between HTTP Stay-Alive and Websockets?


Solution

  • SSE is unidirectional because when you open a SSE connection, only the server can send data to the client (browser, etc.). The client cannot send any data. SSE is a bit older than WebSockets, hence may be the difference between the unidirectional and bi-directional support between these two technos.

    In your use-case, if you open a SSE connection (which is an HTTP connection), only the server will be able to send data. If you wish to send a request to your HTTP service, you will need to open a new "classical" HTTP connection. You will see your browser opening two HTTP connections: 1 for the SSE connection and 1 for the classical HTTP request (short live).

    You can implement a chat with SSE. You can have a SSE connection (hence HTTP) to let the user receives the messages from the server. And you can use POST HTTP requests to enable the user to send his/her messages.

    Note that most of the browsers can open around 6 HTTP/1.x connections to the same host. So, if you use 1 SSE connection, it will remain potentially 5 HTTP/1.x connections. This is only true with HTTP/1.x. With HTTP 2.x, the connections to the same host are multiplexed: so, in theory, you can send as many HTTP requests at the same time as you wish or you can open as many SSE connections as you wish and thus, by passing the limitation of the 6 connections.

    You can have a look at this article (https://streamdata.io/blog/push-sse-vs-websockets/) and this video (https://www.youtube.com/watch?v=NDDp7BiSad4) to get an insight about this technology and whether it could fit your needs. They summarize pros & cons of both SSE and WebSockets.