12 ms·
Server-sent events, WebSockets, and HTTP
- deleted 5y ago[deleted]
- EGreg 5y ago[flagged]
- treve 5y agoI knew what this was going to be before I clicked it. This gets posted way too often any time a new thing is proposed. If the sentiment were universally true, we'd get very few new standards. New ideas get proposed all the time, many of them fail and some are successful. We are better off for that. Don't discourage people from participating in the marketplace of new ideas. It's snarky and not constructive.
- EGreg 5y agoActually I was summarizing his article. The situation he describes in pubsub for Websockets is exactly this.
- treve 5y agoThe way you wrote this sounds like you disagree with my sentiment because I misunderstood your original intent with linking the xkcd, but I understood that you felt that the comic was an apt description.
- josephg 5y agoThats not a summary, any more than "action movie" is a summary of Iron Man. That comic cleverly names a common technical motivation. But it doesn't summarize the work because it removes all the interesting & relevant technical details. Its also really done at this point. That link has been posted 733 times in HN comments[1]. It was funny the first time, but its time to let it die. [1] https://hn.algolia.com/?dateRange=all&page=0&prefix=true&query=%22https%3A%2F%2Fxkcd.com%2F927%22&sort=byPopularity&type=comment https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...
- djrobstep 5y agoI wish the moderators would ban this incredibly annoying comic, which gets posted any time anybody posts anything that might improve any situation, even if it's not standardization-related.
- EGreg 5y agoThat’s kind of how HN is - snarky and dismissive. At least I did it summarizing the actual post. I support actual attempts at improvements. And I don’t eee much issue with websockets implementations. I myself have posted links to stuff I worked hard on for years … not just proposing but implementing and testing for years … and it just gets silently downvoted with an occasional comment about how YouTube sucks or something
- mattsahr 5y agoDownvoted. Youtube sucks.
- leg100 5y agoGod this is tiresome. There are so many good xkcd comic strips that could be posted with more nuance and applicability to the subject matter. But almost everytime a link to xkcd is posted, it is to #927. It's utterly inane. Anyone who frequents HN will have seen it linked before and will know not to bother to link to it again. So why do it?
- politician 5y agoMark mentioned the idea of using edge compute to process protocol traffic. Do any CDNs support edge compute with WebSockets?
- HALtheWise 5y agoCloudflare Durable Objects should
- mmzeeman 5y agoThe best way to do pub/sub on the web with a standard protocol is MQTT (https://mqtt.org https://mqtt.org). It supports websockets, it scales, supports authentication, can handle unreliable networks. We use it exclusively for the soon to be released 1.0 version of Zotonic. See: https://test.zotonic.com https://test.zotonic.com (running on a 4.99 euro Hetzner vps). We developed an independent support javascript library called Cotonic (https://cotonic.org https://cotonic.org) to handle pub/sub via MQTT. This library can also connect to other compliant MQTT brokers. Because MQTT is fairly simple protocol, it is fairly easy to integrate in existing frameworks. Here is an example chat application (https://cotonic.org/examples/chat https://cotonic.org/examples/chat) which uses the open Eclipse broker.
- ShoveItHN 5y agoLook at your first two sentences. You say MQTT supports authentication like MQTT.
- musingsole 5y ago> The best way to do pub/sub on the web with a standard protocol is MQTT Strong disagree. MQTT has no place in a world with WebSockets. MQTT knowledge is so esoteric in comparison. Maybe it's the Haskell of transport protocols: really friggin smart, but not if you're trying to be useful to society at large.
- detaro 5y agoMQTT is neither "esoteric" or "not useful to society at large" nor is WebSockets vs MQTT even a useful contrast, since WebSockets to a large degree addresses a different level of the stack (and indeed "MQTT over WebSockets" is a common way of deploying it).
- mmzeeman 5y agoMQTT is a proven protocol. It's design started started more than 20 years ago. The protocol was designed to be easy to implement. It is simple to implement if you want. There are multiple brokers, and client libraries available. So why invent a new protocol, when an open, standardised protocol already exists. Open pages in a browser are not that different from IoT devices.
- josephg 5y agoIn case people don't know, Mark Nottingham (the author) is the chair of the HTTP working group at the IETF. He isn't just some guy with opinions on the internet. (Sorry mnot!) I've never found pub/sub quite the right abstraction, because almost every implementation I've seen has race conditions or issues on reconnect. Usually its possible to lose messages during reconnection, and there's often other issues too. I usually want an event queue abstraction, not pub/sub. I met mnot a few years ago when we (the braid group) took a stab at writing a spec for HTTP based streaming updates[1]. Our proposal is to do state syncronization around a shared objects (the URL). Each event on the channel is (explicitly or implicitly) an update for some resource. So: - The document (resource) has a version header (ETag?). - Each event sent on the stream is a patch which changes the version from X to Y. Patches can either be incremental ("insert A at position 5") or if its small, just contain a new copy of the document. - You can reconnect at any time, and specify a known version of the document. The server can bring you up to date by sending the patches you missed. If the server doesn't store historical changes, it should be able to just send you a fresh copy of the document. After that, the subscription should drip feed events as they come in. One nice thing about this is that CDNs can do highly efficient fan-out of changes. A cache could also use braid to subscribe to resources which change a lot on the origin server, in order to keep the cached values hot. [1] https://datatracker.ietf.org/doc/html/draft-toomim-httpbis-braid-http-02 https://datatracker.ietf.org/doc/html/draft-toomim-httpbis-b... We've done some revisions since then but have been working on getting more running code before pushing forward more with the approach. Most recent draft & issues: https://github.com/braid-org/braid-spec/blob/master/draft-toomim-httpbis-braid-http-03.txt https://github.com/braid-org/braid-spec/blob/master/draft-to...
- samwillis 5y agoDid you consider using CRDTs for your document sync? It sounds like what you were implementing was somewhere between OTs and CRDTs and trying to create a standard event protocol for them? CRDTs remove the need keeping track of all (or any just recent) revisions on the server as you would with OTs, your server can be stateless and just act as a message broker between clients. Edit: Should have followed your links, yes that’s exactly what you are doing. https://braid.org/ https://braid.org/
- 5y ago
- ShoveItHN 5y agoInteresting. I'm writing an application that will control devices over HTTP with a REST-style API (defined in OpenAPI). But we also want those devices to be able to alert the controlling application to events without being polled. This won't be a large datastream, but rather the occasional update of progress or notification of a state change. I was considering Websockets or MQTT (or both), so server-sent events sound like a direct and possibly superior competitor. But from a design standpoint, what do you do? Just do a GET on some general "status" endpoint to open this SSE stream and then have the server send everything down this pipe indefinitely?
- samwillis 5y agoYes, it’s just a GET that stays open, super simple. There are various client libs that support SSE outside of browsers, worth having a look if there is one for the language you are using.
- ShoveItHN 5y agoThanks! I haven't done much network programming. While this SSE channel stays open, the controlling app will need to be able to continue to do additional traditional GET, POST, etc. calls to the server. How are responses to those distinguished from data coming in from SSE?
- eldelshell 5y agoSSE has its own API (EventSource), it's not a normal fetch/ajax request. https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events https://developer.mozilla.org/en-US/docs/Web/API/Server-sent...
- ShoveItHN 5y ago
- drothlis 5y agoSame way that if you make 2 "normal" GETs simultaneously to the same server the responses don't get mixed up, i.e. they'll be separate HTTP Connections which are separate TCP connections: > Each HTTP connection maps to one underlying transport connection. -- https://httpwg.org/http-core/draft-ietf-httpbis-messaging-latest.html#rfc.section.9.1 https://httpwg.org/http-core/draft-ietf-httpbis-messaging-la... TCP uses "port numbers" to identify different connections. 2 different connections from your PC to the same web server will use 2 different "source" ports. A port is just a number in the TCP header. https://en.wikipedia.org/wiki/Transmission_Control_Protocol#TCP_ports https://en.wikipedia.org/wiki/Transmission_Control_Protocol#... HTTP/1.1 added pipelining, so you can make several requests on the same TCP connection before receiving a response. But the (complete) responses must arrive in the same order of the requests so it doesn't work for SSE. HTTP/2 added request & response multiplexing on the same TCP connection. But (according to the OP) there are some limitations that affect SSE.
- jkarneges 5y ago> The question, then, is how we enable intermediation for pub/sub My company (Fanout) is attempting to solve this via the Generic Realtime Intermediary Protocol: https://pushpin.org/docs/protocols/grip/ https://pushpin.org/docs/protocols/grip/ The idea is to enable origin servers to delegate connection management to a proxy tier, without introducing a new client-facing protocol.
- jokoon 5y agoIt's easy to point out that it's not trivial to make async stuff with web technologies. To be completely honest, when you look at the big picture, HTML was designed to be a static document format. I really wish some new format or standard would be built from the ground up. HTML JS was never a good format, it just got popular to fight microsoft.
- spullara 5y agoMicrosoft basically invented the modern web with XMLHttpRequest. https://en.wikipedia.org/wiki/XMLHttpRequest#History https://en.wikipedia.org/wiki/XMLHttpRequest#History
- jcelerier 5y agohttps://www.canonic.com/ https://www.canonic.com/
- austincheney 5y agoThat might have been true a decade ago, but no longer. With a bit of practice wiring things async is trivial easy. You have plenty of options now with http2, web sockets, and SSE. The hardest part, by far, in any of this is certificate management for the mandatory push to TLS for everything. Even that is much easier now with OpenSSL almost everywhere and Let’s Encrypt.
- rektide 5y agoNo mention of what browsers do for notifications, Web Push Protocl[1]. Which makes sense only in the context of the one of the ancient grand-daddy issues of Fetch being completely ignored by the powers that be[2], & the browser & the browser alone (not the page) having the capability to hear & observe HTTP2+ PUSH requests coming in. This github issue to let a fetch request hear PUSH responses come back at it has been mostly ignored, for 3/4 a decade. Meanwhile Chrome is saying people don't use Push. Yeah, well, because ye jerknuts have diluted & made unusable the best part of it: the ability to be responsive to resources coming at us. What a sad truckload of tragedy this undelivered capability has been. To invent a new HTTP, HTTP2, with new capabilities, then spend most of a decade ignoring & denying developers access to the best parts of what you just invented. Irony & tragedy. Now they're taking away PUSH[3], having never made it usable at all. Classic frigging Google, what frigging fickle monsters, incapable of even the most basic follow-through on what they start. [1] https://datatracker.ietf.org/doc/html/rfc8030 https://datatracker.ietf.org/doc/html/rfc8030 [2] https://github.com/whatwg/fetch/issues/51 https://github.com/whatwg/fetch/issues/51 [3] https://groups.google.com/a/chromium.org/g/blink-dev/c/K3rYLvmQUBY/m/vOWBKZGoAQAJ https://groups.google.com/a/chromium.org/g/blink-dev/c/K3rYL...
- chrismorgan 5y agoI think you may be misunderstanding the purpose of RFC 8030, or if you do understand it (and after more careful contemplation of your wording, I think you do) you’re conflating two different things. It’s not something for web pages to implement or use, but for user agents to implement, providing a standard way of delivering events fielded via the Push API (which is for web content to use, and works well), because browsers were all implementing their own stuff for that, making interoperability or hosting your own push service (which is on the public internet and receives events and then sends them to the browser somehow) difficult. This happens to use HTTP/2 PUSH_PROMISE frames, and it’s a good use of them. But that doesn’t imply anything about exposing HTTP/2 Server Push to arbitrary web content. (I have no idea of the implementation status of RFC 8030, whether any or all user agents have replaced their own ad hoc systems with it.) The fact of the matter is that HTTP/2 Server Push really just didn’t pan out for general web content: its original intended purpose flopped, turning out to cause more trouble than it solves; cache digests could make this probably not so, but they make it even more complex, and add a little overhead, so that based on what’s been seen so far, implementer consensus (consensus, not just Google) is that it’s just not worth trying. Sad but true. As for the remaining possible cases, they’re served about as well and more compatibly by older techniques. (And compatibility is important: you emphatically cannot depend on HTTP/2 working, so you mustn’t require HTTP/2 features, so there’s not a great deal of purpose in implementing them at all.) So in the end, exposing HTTP/2 Server Push to client code is probably a net loss, significant complexity spent for significant risks, insignificant uptake, and negligible concrete benefits. Google is bad, sure, but I don’t think this is an example of that.
- eldelshell 5y agoMy experience with SSE so far (take this as recommendations if you wish) You need to implement a server-side heartbeat feature. You need to handle the close event from EventSource and be able to reconnect. Tabs can be problematic. When you subscribe, you use a URL with a nominal ID to identify the client. For example, on a chat app, you would use /api/sse/userA/subscribe Problem is, if userA starts opening tabs, each tab creates a new subscription for userA so you need to randomize each connection (userA-UUID). If you don't use a nominal id, the server won't know to which subscriber to send the data and you don't want to broadcast all your chats. I've used the Broadcast channel API in conjunction with SSE to have only one tab handle the SSE connection, and broadcast incoming SSEs to the other tabs which also reduces the number of connections to the server to one. On the server it's also a PITA because not all instances/pods have the subscribers list. The way I've found to solve this is with clustering the instances with Hazelcast or Redis or a MQ. But once you figure out all this, SSE works quite well.
- sbergjohansen 5y agoAlso, when using an nginx reverse proxy, including 'X-Accel-Buffering: no' in the HTTP header of the server response may be required to keep events from being buffered.
- samwillis 5y agoThis chimes a lot with my experience. Although I think SSEs are brilliant if the stack I’m using supports Websockets I would probably default to them even for a simple event stream now. To add to your list of problems, I have had memory leaks with SSE responses stuck open on the server even when the client disconnects. Resorted to killing the response on the server every couple of minutes and relying on the client reconnecting.
- qwtel 5y agoSounds like a service worker, for which there's only one active at a time for all tabs (and can communicate with them) could help with your client side issues.
- 5y ago
- dSebastien 5y agoI'd love to see support for pub/sub as part of HTTP.
- cryptica 5y agoI don't understand this mindset. HTTP was a protocol designed for transferring text files. It literally means 'HyperText Transfer Protocol'. Its use case has been getting broader and broader over time. Why does everyone want it to be a silver bullet? There are no silver bullets. Jack of all trades, master of none. WebSockets is great because it's a separate protocol and can be dealt independently by browser and server vendors as security and functional requirement change. HTTP was never designed for pub/sub... How does the additional layer of complexity provided by HTTP for file transfers (e.g. request headers with each request, response headers, cookies sent in each request, mime types, etc...) benefit us for the pub/sub use case? It just adds overhead and makes it harder for vendors to fully implement HTTP. What used to be a simple protocol is becoming prohibitively complicated.
- pbowyer 5y ago> Why does everyone want it to be a silver bullet? I agree with this sentiment. But mnot spells out well in his article why adding it to HTTP would be pragmatic (CDNs, standardised, caching)
- tjpnz 5y agoWhen would you use WebSockets versus SSE? The introductory example most tutorials on WS give is for chat, yet it looks like you could implement the same functionality using a combination of REST and SSE. That would allow you to stay in HTTP land which seems desirable based on all of the issues I've read about people having here.
- toomim 5y agoYour question is the topic of the article [1] Mnot was replying to. [1] https://news.ycombinator.com/item?id=30312897 https://news.ycombinator.com/item?id=30312897
- samwillis 5y agoSSE are single direction (server to client), you could use a http get/post for message from the client but then if you have multiple servers it could land of another server. Websockes allow you to have the server end processed in one place. The big advantage of SSE when doing a simple event stream from the server is that they can be implemented in stacks that don’t support Websockes, such as many of the older Python frameworks (i.e. Django) built on top is WSGI. To use Websockes with these frameworks they either need upgrading to ASGI (or equivalent) or you have to run an additional server process for Websockes. I do a lot of Django, SSE are super easy with it, just a StreamingResponce implementing the SSE protocol. I have then tended to use Gevent with Gunicorn to handle the long streaming responses rather than the default threaded workers. There are few caveats around implementing a heartbeat event and ensuring they are closed properly when the client disconnects. This can be super annoying, I tent to kill the connection every couple of minutes as you don’t always know when the client has disconnected. Also buffering in reverse proxy’s need to be worked around. To be honest though as Django gains better support for Websockes I would probably use them over SSE even for a single direction event stream, less edge cases to think about.
- merb 5y agobtw. sse also works good with http/2
- deleted 5y ago
- the_gipsy 5y agoCan Web Push Notifications not also be considered as an alternative? They are quite different from SSE and WebSockets in some aspects. Using Web Workers for some core feature shouldn't be considered lightly. But the end result is pub/sub, so it's worth to check out. https://developer.mozilla.org/en-US/docs/Web/API/Push_API/Best_Practices https://developer.mozilla.org/en-US/docs/Web/API/Push_API/Be...
- karl42 5y agoTechnically it would fit nicely. Unfortunately, it requires the user to explicitly give permissions to show notifications to the website, even if you don't show any notifications. This is a blocker for its usage in many cases.
- mmis1000 5y agoI think you probably mean web Notification. Although it is always use with Web Push. And also it is generally rate-limited due to its default usage (display a message to user). On the other side, Websocket and SSE talks to program, there is just no rate limit thing exist.
- aww_dang 5y agoJetty/Cometd abstracts away the problems mentioned in the comments here. I enjoyed it for personal projects without the enterprisey overhead. It does integrate with that stuff if you're into that. Just my personal preference. Not claiming anything beyond that.
- nesarkvechnep 5y agoOff-topic but I would like to share with all of you a proposal from Mark Nottingham on HTTP cache channels[1]. Sadly it went nowhere but in my opinion was and still is very promising idea. [1] https://datatracker.ietf.org/doc/html/draft-nottingham-http-cache-channels-01 https://datatracker.ietf.org/doc/html/draft-nottingham-http-...
- stavros 5y agoI'm just now planning to make a web app with a Django backend that will need simple notifications on the frontend, and I'd like to keep the frontend as light as possible (no React, for example). What would you recommend? Websockets? MQTT?
- musingsole 5y agoWebSockets Frameworks like JustPy have used it to couple the frontend to the backend and have a Python server doing all the logic work (i.e. frontend just passes everything over WebSockets to the server and asked what to do). It's an awesome demonstration of what WebSockets can do. MQTT has no place on the web. It barely has a place in IoT and should lose all rights to that claim yesterday.
- nickjj 5y agoI don't know why but when I read this from the article: > Because WebSockets is effectively a blank canvas, there are a lot of choices to be made when designing a protocol on top of it, and no one way of doing it has yet gained momentum. It immediately reminded me of Flash. Flash was basically a blank canvas where you can do just about anything. Turns out that's not a very good model for a number of reasons -- one of which being it turns everything you do into a snowflake and you need to invent your own patterns and abstractions instead of leaning on an extremely well thought out but more limited approach that's been vetted for many years before Flash was a thing. I don't think WebSockets are really bad but it makes me internally wince whenever I see tech stacks trying to push using them for everything, even for transitioning between pages with no broadcast mechanism. Now I see part of the allure though. If you're a language or framework maker you get to make decisions at the protocol level instead of sticking to decades of standards which is the awesomeness of HTTP. I'm all for sprinkling in tiny bits of WebSockets when it makes sense, ie. doing actual pub/sub things like showing notifications or showing messages like "4 new people commented on your post, click here to show them". In the same way that it felt ok to use a little bit of Flash back in the day for specific functionality instead of throwing out everything and trying to make your entire site in Flash.
- dpeck 5y ago| Flash was basically a blank canvas where you can do just about anything. Turns out that's not a very good model for a number of reasons I don’t think of this as a bad thing. There was exactly a lot of what you say happening around that time, but the time when Flash was biggest was also a time of massive creativeness on the web. I think we’re missing some of that now, and I’m more than ok with our collective “pendulum” swinging back towards the blank canvas than the overfit tech world we have today.
- PragmaticPulp 5y agoWebSockets are actually fantastic for providing low overhead and high flexibility. It’s really not difficult to use any number of modern frameworks to do things like encode and decode from wire formats or even multiplex across the channel. WebSockets shouldn’t be approached as a “from scratch” communication method unless you have very specific needs or your application is dead simple. Everyone else should take advantage of the numberous libraries available to help with the basics. > I don't think WebSockets are really bad but it makes me internally wince whenever I see tech stacks trying to push using them for everything, even for transitioning between pages with no broadcast mechanism. I’m not up to date with the less popular web frameworks. Which frameworks do that?
- anderspitman 5y agoGreat article. This stuff is fun to read about. But none of this complexity is necessary. Most of the world's "cloud" needs could be handled by each extended family of 100-200 people have a couple nerdy cousins administering a backed-up Nextcloud instance (maybe Sandstorm or Cloudron if you really want to go nuts).
- anoplus 5y agoSSA 24q1H waec aqgwfxd
- dpweb 5y agoBeen on SSE since about 10 years ago, and seems a nice time to modernize and move to something that supports peer to peer (browser) and not just client server. Anyone using anything like that now?
- olesku 5y agoI've been working on a pub/sub server that supports both Websockets and SSE as a hobby project for a couple of years. It have been successfully implemented and is used in production on some high traffic sites with 300k+ simultaneous connections. If someone are interested the projects webpage can be found here: https://github.com/olesku/eventhub https://github.com/olesku/eventhub
- tomberek 5y agoSSE has been extremely useful for my purposes. And the issues with scaling it are similar in nature to scaling and getting a similar feature set out of any solution. But in terms of speed to PoC/MVP nothing has been as easy as SSE. The final reasoning is that it can easily be inspected, debugged, curl'd, and so forth. Not sure how often this is done, but I've been sending query parameters along with the request and using it to stream results back to the client for low-latency initial responses to long-running API calls.
- romaniv 5y agoI understand that right now people just want some way to make pages update with minimum fuss, but when you start talking about extending HTTP (even more), that automatically brings up the question of whether you're solving the wrong problem. > What's the best way to do pub/sub on the Web? I think it's the wrong question. Or at least it will become the wrong question at some point. Should we be pushing for web technologies even when we need communication models that the Web clearly was not designed for? After having used NATS for some things, web services, web sockets and all other related stuff feels archaic and byzantine. Too much ducktape on top of a very simple, but limited idea of hyperlinked documents.
- joelbondurant0 5y ago