Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I've used SSE and websockets a lot. I like SSE. But it has two key weaknesses compared to websockets.

Firstly, it's unidirectional. The server sends a stream of events to the client, but the client can't send anything back. That might not be a problem at a purely semantic level (maybe the client doesn't have anything to send back), but it means you can't implement application-level heartbeating or flow control in-band; there is no way for a server to know if a client is reading messages, and if it is, whether it is keeping up with the stream. You can use TCP-level state management and flow control for this, which is inadequate, because there are all sorts of failure modes it doesn't catch, or doesn't catch quickly. Or you can implement the back-channel via separate HTTP requests, which is pretty ugly.

Secondly, SSE connections are subject to the browser's HTTP connection limit - i think most browsers these days have a limit of six connections to any given origin. If you have one connection per page, the user can open six tabs, and then any further attempts to access your site, using SSE or not, will mysteriously fail, because they can't open a connection. Websockets are not subject to this limit; they have a separate per-origin limit, which is usually much larger - 200 for Firefox, 255 for Chrome (although Chrome also has a global limit of 255 websockets?). For SSE, you may be able to work around this by port or hostname sharding, or sharing a single connection using a web worker, but all of these are complicated and intrusive. Now, this conversation started with talking about HTTP/2, and HTTP/2 does solve this, because it can multiplex many SSE connections over a single TCP connection (at the cost of head-of-line blocking on packet drops). But now you're making HTTP/2 a hard requirement for deployment - fallback to HTTP/1.1 just won't work reliably.



Valid points, the request limit in particular. On the other hand, there is some smart resource management in the user agent for EventSource, IIRC, which I'm not sure exists for websockets. I feel HTTP/2 as a requirement is acceptable but that obviously depends on the use case.

That said, I still feel SSE is both underutilized and sadly unknown.


Both downsides are fixed by using http/2, right? Heartbeat seems trivial to implement using HTTP/2 PING frame. And you already mentioned the stream sharing, which IMO is much better than the state of each tab on the same website opening its own TCP socket, pretty much a resource exhaustion hell (browsers didn't implement websockets on top of h2 last time I checked).

Websockets do have an advantage over SSE: they get binary streams instead of text.


HTTP/2 doesn't fix the former downside. It doesn't give you a general bidirectional stream, so you can't implement flow control. I'm not aware of a browser API for sending (or inhibiting) HTTP/2 pings - is there one? In the absence of one, you also can't use HTTP/2 to implement an application-level heartbeat.

To expand on this a bit, a problem i have run into with SSE is that the socket is open, some part of the client (the browser or HTTP client) is reading data, but it is not being processed, because the actual application code on the client is stuck or broken or something. To deal with that, you have to be able to drive feedback from the application code on the client to the server.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: