[HN Gopher] Server-Sent Events: an alternative to WebSockets
       ___________________________________________________________________
        
       Server-Sent Events: an alternative to WebSockets
        
       Author : tyrion
       Score  : 381 points
       Date   : 2022-02-12 14:05 UTC (8 hours ago)
        
 (HTM) web link (germano.dev)
 (TXT) w3m dump (germano.dev)
        
       | lima wrote:
       | One issue with SSE is that dumb enterprise middleboxes and
       | Windows antivirus software break them :(
       | 
       | They'll try to read the entire stream to completion and will hang
       | forever.
        
         | bullen wrote:
         | I managed to get through almost all middle men by using 2
         | tricks:
         | 
         | 1) Push a large amount of data on the pull (the comet-stream
         | SSE never ending request) response to trigger the middle thing
         | to flush the data.
         | 
         | 2) Using SSE instead of just Comet-Stream since they will see
         | the header and realize this is going to be real-time data.
         | 
         | We had 99.6% succes rate on the connection from 350.000 players
         | from all over the world (even satellite connections in the
         | Pacific and modems in Siberia) which is a world record for any
         | service.
        
           | Matheus28 wrote:
           | While 350k simultaneous connections is nice, I'd be extremely
           | skeptical of that being any kind of world record
        
             | [deleted]
        
             | bullen wrote:
             | The world record is not the 1.100 concurrent users per
             | machine (T2 small then medium on AWS) we had at peak, but
             | the 99.6% connections we managed. All other multiplayer
             | games have ~80% if they are lucky!
             | 
             | 350.000 was the total number of players during 6 years.
        
       | szastamasta wrote:
       | My experience with sse is pretty bad. They are unreliable, don't
       | support headers and require keep-alive hackery. In my experience
       | WebSockets are so much better.
       | 
       | Also ease of use doesn't really convince me. It's like 5 lines of
       | code with socket.io to have working websockets, without all the
       | downsides of sse.
        
         | mikojan wrote:
         | What? How do they not support headers?
         | 
         | You have to send "Content-Type: text/event-stream" just to make
         | them work.
         | 
         | And you keep the connection alive by sending "Connection: keep-
         | alive" as well.
         | 
         | I've never had any issues using SSEs.
        
           | szastamasta wrote:
           | I mean you cannot send stuff from client. If you're using
           | tokens for auth and don't want to use session cookies, you
           | end with ugly polyfils.
        
             | coder543 wrote:
             | > If you're using tokens for auth and don't want to use
             | session cookies
             | 
             | That sounds like a self-inflicted problem. Even if you're
             | using tokens, why not store them in a session cookie marked
             | with SameSite=strict, httpOnly, and secure? Seems like it
             | would make everything simpler, unless you're trying to
             | build some kind of cross-site widget, I guess.
        
               | szastamasta wrote:
               | I need to work with more than 1 backend :)
        
               | coder543 wrote:
               | This is such an opaque response, I don't know what else
               | could be said. If you're sending the same token to
               | multiple websites, something feels very wrong with that
               | situation. If it's all the same website, you can have
               | multiple backends "mounted" on different paths, and that
               | won't cause any problems with a SameSite cookie.
        
               | szastamasta wrote:
               | Then you need a single point of failure that is handling
               | session validation. Without it part of your app might
               | work even without your sessions storage.
        
               | coder543 wrote:
               | You can store a JWT in a session cookie. You don't need a
               | SPoF for session validation, if that's not what you want.
        
           | Kyro38 wrote:
           | SSE won't work with tokens, see
           | https://stackoverflow.com/questions/28176933/http-
           | authorizat...
        
         | ricardobeat wrote:
         | Mind expanding on your experience and how are websockets more
         | reliable than SSE? one of the main benefits of SSE is
         | reliability from running on plain HTTP.
        
           | dnautics wrote:
           | I've done both. One big one is Sse connections will
           | eventually time out, and you WILL have to renegotiate, so
           | there will be a huge latency spike on those events. They are
           | easier in elixir than most pls, but honestly if you're using
           | elixir, you might as well use phoenix's builtin we socket
           | support.
        
             | odonnellryan wrote:
             | How is this different from websockets? They will eventually
             | close for various reasons, sometimes in not obvious ways.
        
             | bullen wrote:
             | Not if you send "noop" messages.
        
               | dnautics wrote:
               | In my experience, sse times out way more than ws, even if
               | you are always sending (I was streaming jpegs using sse).
        
         | jFriedensreich wrote:
         | sounds like you did not really evaluate both technologies at
         | the heart but only some libraries on top?
        
           | szastamasta wrote:
           | Yeah, sorry. In socket.io it's 2 lines. You need 5 lines with
           | browser APIs :).
           | 
           | You simply get stuff like auto-reconnect and graceful
           | failover to long polling for free when using socket.io
        
             | coder543 wrote:
             | SSE EventSource also has built-in auto-reconnect, and it
             | doesn't even need to support failover to long polling.
             | 
             | Neither of those being built into a third party websocket
             | library are actually _advantages_ for websocket... they
             | just speak to the additional complexity of websocket. Plus,
             | long polling as a fallback mechanism can only be possible
             | with server side support for both long polling and
             | websocket. Might as well just use SSE at that point.
        
         | bullen wrote:
         | They don't support headers in javascript, that is more a
         | problem with javascript than SSE.
         | 
         | Read my comment below about that.
        
         | 88913527 wrote:
         | HTTP headers must be written before the body; so once you start
         | writing the body, you can't switch back to writing headers.
         | 
         | Server-sent events appears to me to just be chunked transfer
         | encoding [0], with the data structured in a particular way (at
         | least from the perspective of the server) in this reference
         | implementation (tl,dr it's a stream):
         | 
         | https://gist.github.com/jareware/aae9748a1873ef8a91e5#file-s...
         | 
         | [0]: https://en.wikipedia.org/wiki/Chunked_transfer_encoding
        
           | patrickthebold wrote:
           | Maybe I misunderstood your claim, but there is:
           | https://developer.mozilla.org/en-
           | US/docs/Web/HTTP/Headers/Tr...
           | 
           | Which seems to be what you need to send 'headers' after a
           | chunked response.
        
             | 88913527 wrote:
             | You understood correctly; I was mis-informed. Today I
             | learned about the "Trailer" header. I'm curious how HTTP
             | clients handle that. A client like window.fetch will
             | resolve with a headers object-- does it include the
             | trailers or not? I'd have to test it out.
        
       | bullen wrote:
       | I made the backend for this MMO on SSE over HTTP/1.1:
       | 
       | https://store.steampowered.com/app/486310/Meadow/
       | 
       | We have had a total of 350.000 players over 6 years and the
       | backend out-scales all other multiplayer servers that exist and
       | it's open source:
       | 
       | https://github.com/tinspin/fuse
       | 
       | You don't need HTTP/2 to make SSE work well. Actually the HTTP/2
       | TCP head-of-line issue and all the workarounds for that probably
       | make it harder to scale without technical debt.
        
         | bastawhiz wrote:
         | Can you explain how H2 would make it harder to scale SSE?
        
           | bullen wrote:
           | The mistake they did was to assume only one TCP socket should
           | be used; the TCP has it's own head-of-line limitations just
           | like HTTP/1.1 has if you limit the number of sockets
           | (HTTP/1.1 had 2 sockets allowed per client, but Chrome
           | doesn't care...) it's easily solvable by using more sockets
           | but then you get into concurrency problems between the
           | sockets.
           | 
           | That said if you, like SSE on HTTP/1.1; use 2 sockets per
           | client (breaking the RFC, one for upstream and one for
           | downstream) you are golden but then why use HTTP/2 in the
           | first place?
           | 
           | HTTP/2 creates more problems than solutions and so does
           | HTTP/3 unfortunately until their protocol fossilizes which is
           | the real feature of a protocol, to become stable so everyone
           | can rely on things working.
           | 
           | In that sense HTTP/1.1 is THE protocol of human civilization
           | until the end of times; together with SMTP (the oldest
           | protocol of the bunch) and DNS (which is centralized and
           | should be replaced btw).
        
             | jupp0r wrote:
             | The issues with TCP head-of-line blocking are resolved in
             | HTTP/3 (QUIC).
        
               | bullen wrote:
               | Sure but then HTTP/3 is still binary and it's in flux
               | meaning most routers don't play nice with it yet and
               | since HTTP/1.1 works great for 99.9% of the usecases I
               | would say it's a complete waste of time, unless you have
               | some new agenda to push.
               | 
               | Really people should try and build great things on the
               | protocols we have instead of always trying to re-discover
               | the wheel, note: NOT the same as re-inventing the wheel:
               | http://move.rupy.se/file/wheel.jpg
        
               | bushbaba wrote:
               | For FANG scale, a 1% performance improvement for certain
               | services has measurable business results.
               | 
               | Take Snap. Say they reduced time to view a snap by 10ms.
               | After 100 snaps that's an additional 1 second of
               | engagement. This could equate to an additional ad
               | impression every week per user. Which is many millions of
               | additional revenue.
        
               | vlovich123 wrote:
               | HTTP/3 is E2E encrypted and built on UDP. What does "most
               | routers don't play nice with it yet" mean in that
               | context? Do you mean middleware boxes/routers rather than
               | end user routers?
        
               | ikiris wrote:
               | It means they don't actually understand networking, but
               | think they do.
        
               | klabb3 wrote:
               | > HTTP/3 is E2E encrypted
               | 
               | Please elaborate.
        
               | homarp wrote:
               | https://www.youtube.com/watch?v=J4fR5aztSwQ - Securing
               | the Next Version of HTTP: How QUIC and HTTP/3 Compare to
               | HTTP/2
               | 
               | "QUIC is a new always-encrypted general-purpose transport
               | protocol being standardized at the IETF designed for
               | multiplexing multiple streams of data on a single
               | connection. HTTP/3 runs over QUIC and roughly replaces
               | HTTP/2 over TLS and TCP. QUIC combines the cryptographic
               | and transport handshakes in a way to allow connecting to
               | a new server in a single round trip and to allow
               | establishing a resumed connection in zero round trips,
               | with the client sending encrypted application data in its
               | first flight. QUIC uses TLS 1.3 as the basis for its
               | cryptographic handshake.
               | 
               | This talk will provide an overview of what the QUIC
               | protocol does and how it works, and then will dive deep
               | into some of the technical details. The deep dive will
               | focus on security-related aspects of the protocol,
               | including how QUIC combines the transport and
               | cryptographic handshakes, and how resumption, including
               | zero-round-trip resumption works. This will also cover
               | how QUIC's notion of a connection differs from the
               | 5-tuple sometimes used to identify connections, and what
               | QUIC looks like on the wire.
               | 
               | In addition to covering details of how QUIC works, this
               | talk will also address implementation and deployment
               | considerations. This will include how a load balancer can
               | be used with cooperating servers to route connections to
               | a fleet of servers while still maintaining necessary
               | privacy and security properties. It will also look back
               | at some of the issues with HTTP/2 and discuss which ones
               | may need to be addressed in QUIC implementations as well
               | or are solved by the design of QUIC and HTTP/3."
        
               | anderspitman wrote:
               | For me the question is not so much "yet" as "maybe
               | never", since some networks block UDP altogether, and
               | HTTP/3 has a robust fallback mechanism.
        
               | fwsgonzo wrote:
               | While I agree, we shouldn't discount one less RTT for
               | encrypted connections. Latency is a problem that never
               | really goes away, and we can only try to reduce RTTs.
        
             | y4mi wrote:
             | > _and DNS (which is centralized and should be replaced
             | btw_
             | 
             | So much nonsense in a single paragraph, amazing.
             | 
             | If anything DNS is _less_ centralized then http and SMTP.
             | Its a surprisingly complicated system for what it does
             | because of all the caching etc, but calling it more
             | centralized then http is just is just ignorant to a silly
             | degree
        
         | dlsa wrote:
         | Couldn't find a license file in the root folder of that github.
         | I found a license in a cpp file buried in the sec folder. You
         | should consider putting the licensing for this kind of project
         | in a straightforward and locatable place.
        
         | smashah wrote:
         | Love your hybrid model via gumroad! I do something similar for
         | my own open-source project
         | 
         | https://github.com/open-wa/wa-automate-nodejs
         | 
         | There should be some sort of support group for those of us
         | trying to monetize (sans donations) our open source projects!
        
         | jayd16 wrote:
         | >backend out-scales all other multiplayer servers
         | 
         | Can you explain what you mean here? What was your peak active
         | user count, what was peak per server instance, and why you
         | think that beats anything else?
        
           | rlabrecque wrote:
           | Agreed, I'm curious as well. We load tested with real-clients
           | faux-users, up to 1 million concurrent. And only stopped at 1
           | million because the test was becoming cost prohibitive.
        
         | shams93 wrote:
         | Its a lot easier to scale than websockets where you need a pub
         | sub solution and a controller to published shared state
         | changes. See is really simply incomparision
        
         | herodoturtle wrote:
         | Nice work, thanks for sharing.
        
         | stavros wrote:
         | Probably not the same person, but did you ever play on RoD by
         | any chance?
        
           | bullen wrote:
           | Probably not, since I dont know what RoD is.
        
             | stavros wrote:
             | I thought so, thanks!
        
         | HWR_14 wrote:
         | Your license makes some sense, but it seems to include a
         | variable perpetual subscription cost via gumroad. Without an
         | account (assuming I found the right site), I have no idea what
         | you would be asking for. I recommend making it a little clearer
         | on the landing page.
         | 
         | That's said, it's very cool. Do you have a development blog for
         | Meadow?
        
           | Aeolun wrote:
           | > MIT but [bunch of stuff]
           | 
           | Not MIT then. The beauty of MIT is that there _is_ no stuff.
        
             | bullen wrote:
             | We already discussed this in an earlier thread, and however
             | bad this looks it's better than my own license.
             | 
             | Here it's clear, you can either use the code without money
             | involved and then you have MIT (+ show logo and some
             | example code is still mine).
             | 
             | If you want money then you have to share some of it.
        
               | dkersten wrote:
               | While I get and support the intent, I don't like this
               | usage of the name of the MIT license. I personally like
               | the license because it tells me at a glance that I can
               | use it for any purpose, commercial or otherwise, as long
               | as the copyright and license is included and that there
               | is no warranty. That's it, no complications, no other
               | demands, no "if it makes X money or not", just I include
               | the copyright and license terms and that's it, I can use
               | the software whichever way I like.
               | 
               | Your license is not that. You have extra conditions that
               | add complexity. I can no longer go "oh like MIT" and
               | immediately use it for any purpose, because you require
               | extras especially if I were to make money. That seems
               | completely against the spirit of the simplicity of the
               | MIT license which says you can do whatever you like,
               | commercial or otherwise, as long as the copyright and
               | license are included.
               | 
               | I think you should make your own license that includes
               | the text of the MIT license, except removing the
               | irrelevant parts (ie the commercial aspects include a
               | caveat about requiring payment). You can still have a
               | separate line of text explaining that the license is like
               | the MIT license but with XYZ changes (basically the text
               | you have now). But the license is not the MIT license and
               | you should therefore have a separate license text that
               | spells it out exactly. Not "its this, except scratch half
               | of it because these additional terms override a good
               | chunk of it".
        
               | smw wrote:
               | I respect your right to license you product however you
               | want, but please don't call that open source.
        
               | bullen wrote:
               | Open-source also means the source is open, what you are
               | looking for is free and honestly nothing is free... if
               | you have a better term I'm open for suggestions.
               | 
               | But really open-source (as in free) is the misnomer here,
               | it should be called free open-source, or FOSS as some
               | correctly name it.
        
               | e12e wrote:
               | That battle has been fought already, and the accepted
               | term is "source available", not "open source". (And gnu
               | adds Free or "libre" software, which is software licence
               | in a way that tries to ensure the "four freedoms" for
               | _all downstream users_ of software - such as freedom zero
               | - the right to run software (no need for eg:
               | cryptographic signature /trusted software - without a way
               | for the _user_ to define trust).
        
               | bullen wrote:
               | Ok, fixed it elsewhere and in my brain... :/ Thx! Can't
               | edit the comment though.
        
               | dragonwriter wrote:
               | > FOSS
               | 
               | FOSS or F/OSS is a combination of Free (as defined by the
               | FSF) and Open Source (as defined by the OSI) (the last S
               | is Software), which recognizes that the two terms, while
               | they come from groups with different ideological
               | motivations, refer to approximately the same substantive
               | licensing features and almost without exception the same
               | set of licenses.
        
               | hamburglar wrote:
               | Personally, while I appreciate the difference from a
               | promotion-of-FOSS point of view, I find it obnoxious that
               | FOSS idealists think they can dictate the usage of the
               | generic phrase "open source" and start these kinds of
               | arguments in threads where non-completely-free software
               | whose source is open comes up. We haven't all agreed on
               | your terminology, and the argument is not "settled"
               | except in the minds of the folks who think everyone
               | should be on board with making this purity distinction.
               | Some people find the distinction uninteresting and don't
               | need to bother themselves with the ideological argument
               | or agree to its terminology. And trying to be the
               | arbiters of language is not a good look for the
               | "information wants to be free" crowd.
        
               | Plasmoid wrote:
               | I've seen these referred to as "Source-available
               | licenses". This would cover things like Mongo's SSPL.
               | 
               | The bare reality is that it's just a commercial license.
        
               | Spivak wrote:
               | Requiring attribution doesn't make something not open
               | source. At best this means that the example code isn't
               | open source.
        
           | bullen wrote:
           | Added link in the readme! Thx.
           | 
           | No, no dev log but I'll tell you some things that where
           | incredible during that project:
           | 
           | - I started the fuse project 4 months before I set foot in
           | the Meadow project office (we had like 3 meetings during
           | those 4 months just to touch base on the vision)! This is a
           | VERY good way of making things smooth, you need to give
           | tech/backend/foundation people a head start of atleast 6
           | months in ANY project.
           | 
           | - We spent ONLY 6 weeks (!!!) implementing the entire games
           | multiplayer features because I was 100% ready for the job
           | after 4 months. Not a single hickup...
           | 
           | - Then for 7 months they finished the game client without me
           | and released without ANY problems (I came back to the office
           | that week and that's when I solved the anti-virus/proxy
           | cacheing/buffering problem!).
           | 
           | I think Meadow is the only MMO in history so far to have ZERO
           | breaking bugs on release (we just had one UTF-8 client bug
           | that we patched after 15 minutes and nobody noticed except
           | the poor person that put a strange character in their name).
        
       | llacb47 wrote:
       | Google uses SSE for hangouts/gchat.
        
       | KaoruAoiShiho wrote:
       | I have investigated SSE for https://fiction.live a few years back
       | but stayed with websockets. Maybe it's time for another look. I
       | pay around $300 a month for the websocket server, it's probably
       | not worth it yet to try to optimize that but if we keep growing
       | at this rate it may soon be.
        
       | oneweekwonder wrote:
       | Personally i use mqtt over websockets, paho[0] is a good js
       | library. It support last will for dc's and the message queue
       | design makes it easy to think of and debug. There also a lot of
       | mq brokers that will scale well.
       | 
       | [0]:
       | https://www.eclipse.org/paho/index.php?page=clients/js/index...
        
       | wedn3sday wrote:
       | This seems fairly cool, and I appreciate the write up, but god I
       | hate it so much when people write code samples that try and be
       | fancy and use non-code-characters in their code samples. Clarity
       | is much more important then aesthetics when it comes to code
       | examples, if Im trying to understand something I've never seen
       | before, having a bunch of extra non-existant symbols does not
       | help.
        
         | asiachick wrote:
         | Agreed. I use them in my editor but I ban them from my blog
         | posts. They aren't helpful to others
        
         | Rebelgecko wrote:
         | Which characters, the funky '[?]'? I've seen those pop up a few
         | other times recently, which makes me wonder if there's some
         | editor extension that just came out that maps != and !==
        
           | roywiggins wrote:
           | They're ligatures.
           | 
           | https://github.com/tonsky/FiraCode
        
         | DHowett wrote:
         | I'm guessing that you are referring to the "coding ligatures"
         | in the author's font selection for code blocks?
         | 
         | You can likely configure your user agent to ignore site-
         | specified fonts.
        
         | loh wrote:
         | Are you referring to the `!==` and `=>` in their code being
         | converted to what appears to be a single symbol?
         | 
         | Upon further inspection, it looks like the actual code on the
         | page is `!==` and `=>` but the font ("Fira Code") seems to be
         | somehow converting those sequences of characters into a single
         | symbol, which is actually still the same number of characters
         | but joined to appear as a single one. I had no idea fonts could
         | do that.
        
           | red_trumpet wrote:
           | That's called a ligature[1], and clasically used for joining
           | for example ff or fi into more readable symbols.
           | 
           | [1] https://en.wikipedia.org/wiki/Ligature_(writing)
        
       | dpweb wrote:
       | Very easy to implement - still using code I wrote 8 years ago,
       | which is like 20 lines client and server, choosing it at the time
       | over ws.
       | 
       | Essentially just new EventSource(), text/event-stream header, and
       | keep conn open. Zero dependencies in browser and nodejs. Needs no
       | separate auth.
        
       | nickjj wrote:
       | This is why I really really like Hotwire Turbo[0] which is a
       | back-end agnostic way to do fast and partial HTML based page
       | updates over HTTP and it optionally supports broadcasting events
       | with WebSockets (or SSE[1]) only when it makes sense.
       | 
       | So many alternatives to Hotwire want to use WebSockets for
       | everything, even for serving HTML from a page transition that's
       | not broadcast to anyone. I share the same sentiment as the author
       | in that WebSockets have real pitfalls and I'd go even further and
       | say unless used tastefully and sparingly they break the whole
       | ethos of the web.
       | 
       | HTTP is a rock solid protocol and super optimized / well known
       | and easy to scale since it's stateless. I hate the idea of going
       | to a site where after it loads, every little component of the
       | page is updated live under my feet. The web is about giving users
       | control. I think the idea of push based updates like showing
       | notifications and other minor updates are great when used in
       | moderation but SSE can do this. I don't like the direction of
       | some frameworks around wanting to broadcast everything and use
       | WebSockets to serve HTML to 1 client.
       | 
       | I hope in the future Hotwire Turbo alternatives seriously
       | consider using HTTP and SSE as an official transport layer.
       | 
       | [0]: https://hotwired.dev/
       | 
       | [1]: https://twitter.com/dhh/status/1346095619597889536?lang=en
        
       | gibsonf1 wrote:
       | Solid has a great solution for this:
       | https://solid.github.io/notifications/protocol
        
       | mmcclimon wrote:
       | SSEs are one of the standard push mechanisms in JMAP [1], and
       | they're part of what make the Fastmail UI so fast. They're
       | straightforward to implement, for both server and client, and the
       | only thing I don't like about them is that Firefox dev tools make
       | them totally impossible to debug.
       | 
       | 1. https://jmap.io/spec-core.html#event-source
        
         | ok_dad wrote:
         | > the only thing I don't like about them is that Firefox dev
         | tools make them totally impossible to debug
         | 
         | You can't say that and not say more about it, haha. Please
         | expand on this?
         | 
         | Also, I'm a Fastmail customer and appreciate the nimble UI,
         | thanks!
        
           | coder543 wrote:
           | I think their information could be outdated. Since Firefox
           | 82, you can supposedly inspect the content of SSE streams:
           | https://developer.mozilla.org/en-
           | US/docs/Tools/Network_Monit...
           | 
           | Before that... yeah, the Firefox dev tools were not very
           | helpful for SSE.
        
             | mmcclimon wrote:
             | Hmm! You're right that I hadn't looked it a while, so I
             | checked before making the comment above. I'm still seeing
             | the same thing I always have, which is "No response data
             | available for this request". Possibly something is slightly
             | wrong somewhere (though Chrome dev tools seem fine on the
             | same), but you've given me something to look into, thanks!
        
               | coder543 wrote:
               | That is interesting. I just tested it myself, and at
               | least for my setup (Firefox on Mac on ARM), the events
               | only showed up in the dev tools if the server closed the
               | SSE connection... so, maybe Firefox still hasn't fully
               | fixed this problem.
        
               | mmcclimon wrote:
               | Yeah, that seems to be the case (confirmed with their
               | little example at https://github.com/mdn/dom-
               | examples/tree/master/server-sent-...). Once the
               | connection is closed you can see things, but that's not
               | particularly useful for debugging!
        
         | dnr wrote:
         | The Fastmail UI is indeed snappy, except when it suddenly
         | decides it has to reload the page, which seems to be multiple
         | times a day these days (and always when I need to search for a
         | specific email). Can you make it do what one of my other
         | favorite apps does: when there's a new version available, make
         | a small pop up with a reload button, but don't force a reload
         | (until maybe weeks later)?
        
       | alin23 wrote:
       | ESPHome (an easy to use firmware for ESP32 chips) uses SSE to
       | send sensor data to subscribers.
       | 
       | I made use of that in Lunar (https://lunar.fyi/#sensor) to be
       | able to adjust monitor brightness based on ambient light readings
       | from an external wireless sensor.
       | 
       | At first it felt weird that I have to wait for responses instead
       | of polling with requests myself, but the ESP is not a very
       | powerful chip and making one HTTP request every second would have
       | been too much.
       | 
       | SSE also allows the sensor to compare previous readings and only
       | send data when something changed, which removes some of the
       | complexity with debouncing in the app code.
        
       | rcarmo wrote:
       | I have always preferred SSE to WebSockets. You can do a _lot_
       | with a minuscule amount of code, and it is great for updating
       | charts and status UIs on the fly without hacking extra ports,
       | server daemons and whatnot.
        
       | njx wrote:
       | My theory why SSE did not take off is because WordPress does not
       | support it.
        
       | havkom wrote:
       | The most compatible technique is long polling (with a re-
       | established connection after X seconds if no event). Works
       | suprisingly well in many cases and is not blocket by any proxies.
        
         | bullen wrote:
         | long-polling are blocked to almost exactly the same extent as
         | comet-stream and SSE. The only thing you have to do is to push
         | more data on the response so that the proxy is forced to flush
         | the response!
         | 
         | Since IE7 is no longer used we can bury long-polling for good.
        
           | notreallyserio wrote:
           | How much more data do you have to send? Is it small enough
           | you aren't concerned about impacting user traffic quotas?
        
             | bullen wrote:
             | Just enough to trigger the buffer... 1024-8192 bytes or
             | something like that... a fart in space since it's just once
             | per session!
        
       | U1F984 wrote:
       | The extra setup step for websocket should not be required:
       | https://caddyserver.com/docs/v2-upgrade#proxy
       | 
       | I also had no problems with HAProxy, it worked with websockets
       | without any issues or extra handling.
        
       | laerus wrote:
       | With WebTransport around the corner I don't think is worth the
       | time investing in learning a, what seems to me, obsolete
       | technology. I can understand it for already big projects working
       | with SSE that don't want to pay the cost of upgrading/changing
       | but for anything new I cannot be bothered since Websockets work
       | good enough for my use cases.
       | 
       | What worries me though is the trend of dismissal of newer
       | technologies as being useless or bad and the resistance to
       | change.
        
         | slimsag wrote:
         | I'm confused, you believe that web developers have a trend of
         | dismissing newer technologies and resistance to change? Have I
         | missed something or..?
        
         | jessaustin wrote:
         | Around the corner? There seems to be nothing about this in any
         | browser. [0] That would put this what, five years out before it
         | could be used in straightforward fashion? Please be practical.
         | 
         | [0] https://caniuse.com/?search=webtransport
        
           | 0xbkt wrote:
           | See https://github.com/Fyrd/caniuse/issues/5707 and
           | https://chromestatus.com/feature/4854144902889472#consensus.
        
             | jessaustin wrote:
             | Thanks for pointing that out. I suppose caniuse missing out
             | on the first experimental version of the first browser to
             | support this isn't terribly misleading. Maybe when they get
             | the basics of the API figured out we can start deprecating
             | other things...
        
         | coder543 wrote:
         | WebTransport seems like it will be significantly lower level
         | and more complex to use than SSE, both on the server and the
         | client. To say that this "obsoletes" SSE seems like a serious
         | stretch.
         | 
         | SSE runs over HTTP/3 just as well as any other HTTP feature,
         | and WebTransport is built on HTTP/3 to give you much finer
         | grained control of the HTTP/3 streams. If your application
         | doesn't benefit significantly from that control, then you're
         | just adding needless complexity.
        
       | anderspitman wrote:
       | My personal browser streaming TL;DR goes something like this:
       | 
       | * Start with SSE
       | 
       | * If you need to send binary data, use long polling or WebSockets
       | 
       | * If you need fast bidi streaming, use WebSockets
       | 
       | * If you need backpressure and multiplexing for WebSockets, use
       | RSocket or omnistreams[1] (one of my projects).
       | 
       | * Make sure you account for SSE browser connection limits,
       | preferably by minimizing the number of streams needed, or by
       | using HTTP/2 (mind head-of-line blocking) or splitting your
       | HTTP/1.1 backend across multiple domains and doing round-robin on
       | the frontend.
       | 
       | [0]: https://rsocket.io/
       | 
       | [1]: https://github.com/omnistreams/omnistreams-spec
        
       | whazor wrote:
       | I tried out server side events, but they are still quite
       | troubling with the lack of headers and cookies. I remember I
       | needed some polyfill version which gave more issues.
        
         | bullen wrote:
         | How do you mean lack of headers and cookies?
         | 
         | That is wrong. Edit: Actually it seems correct (a javascript
         | problem, not SSE problem) but it's a non-problem if you use a
         | parameter for that data instead and read it on the server.
        
           | tytho wrote:
           | You cannot send custom headers when using the built-in
           | EventSource[1] constructor, however you can pass the
           | 'include' value to the credentials option. Many polyfills
           | allow custom headers.
           | 
           | However you are correct that if you're not using JavaScript
           | and connecting directly to the SSE endpoint via something
           | else besides a browser client, nothing is preventing anyone
           | from using custom headers.
           | 
           | [1] https://developer.mozilla.org/en-
           | US/docs/Web/API/EventSource...
        
             | withinboredom wrote:
             | I'm pretty sure I saw him sending headers in the talk. Did
             | you watch the talk?
        
               | tytho wrote:
               | He was likely using a polyfill. It's definitely not in
               | the spec and there's an open discussion about trying to
               | get it added: https://github.com/whatwg/html/issues/2177
        
             | bullen wrote:
             | Aha, well why do you need to send a header when you can
             | just put the data on the GET URL like so
             | "blabla?cookie=erWR32" for example?
             | 
             | In my example I use this code:                       var
             | source = new EventSource('pull?name=one');
             | source.onmessage = function (event) {
             | document.getElementById('events').innerHTML += event.data;
             | };
        
               | tytho wrote:
               | I think that works great! The complaint I've heard is
               | that you may need to support multiple ways to
               | authenticate opening up more attack surface.
        
               | kreetx wrote:
               | What if you use http-only cookies?
        
               | tytho wrote:
               | You can pass a 'withCredentials' option.
        
       | samwillis wrote:
       | I have used SSEs extensively, I think they are brilliant and
       | massively underused.
       | 
       | The one thing I wish they supported was a binary event data type
       | (mixed in with text events), effectively being able to send in my
       | case image data as an event. The only way to do it currently is
       | as a Base64 string.
        
         | jtwebman wrote:
         | Send an event that tells the browser to request the binary
         | image.
        
           | samwillis wrote:
           | In my case I was aiming for low latency with a dynamically
           | generated image. To send a url to a saved image, I would have
           | to save it first to a location for the browser to download it
           | form. That would add at least 400ms, probably more.
           | 
           | Ultimately what I did was run an SSE request and long polling
           | image request in parallel, but that wasn't ideal as I had to
           | coordinate that on the backend.
        
             | bckr wrote:
             | I'm curious if you could have kept the image in memory (or
             | in Redis) and served it that way
        
               | samwillis wrote:
               | That's actually not too far from what we do. The image is
               | created by a backend service with communication (queue
               | and responses) to the front end servers via Redis.
               | However rather than saving the image in its entirety to
               | Redis, it's streamed via it in chunks using LPUSH and
               | BLPOP.
               | 
               | This lets us then stream the image as a steaming http
               | response from the front end, potentially before the jpg
               | has finished being generated on the backend.
               | 
               | So from the SSE we know the url the image is going to be
               | at before it's ready, and effectively long poll with a
               | 'new Image()'.
        
         | keredson wrote:
         | SSE supports gzip compression, and a gzip-ed base64 is almost
         | as small as the original jpg:
         | 
         | $ ls -l PXL_20210926_231226615.*
         | 
         | -rw-rw-r-- 1 derek derek 8322217 Feb 12 09:20
         | PXL_20210926_231226615.base64
         | 
         | -rw-rw-r-- 1 derek derek 6296892 Feb 12 09:21
         | PXL_20210926_231226615.base64.gz
         | 
         | -rw-rw-r-- 1 derek derek 6160600 Oct 3 15:31
         | PXL_20210926_231226615.jpg
        
           | samwillis wrote:
           | Quite true, however from memory Django doesn't (or didn't)
           | support gzip on streaming responses and as we host on Heroku
           | we didn't want to introduce another http server such as Nginx
           | into the Heroku Dyno.
           | 
           | As an aside, Django with Gevent/Gunicorn does SSE well from
           | our experience.
        
       | goodpoint wrote:
       | --- WebSockets cannot benefit from any HTTP feature. That is:
       | No support for compression         No support for HTTP/2
       | multiplexing         Potential issues with proxies         No
       | protection from Cross-Site Hijacking
       | 
       | ---
       | 
       | Is that true? The web never cease to amaze.
        
         | __s wrote:
         | WebSockets support compression (ofc, the article goes on to
         | detail this & point out flaws. I'd argue that compression is
         | not generally useful in web sockets in the context of many
         | small messages, so it makes sense to be default-off for servers
         | as it's something which should be enabled explicitly when
         | necessary, but the client should be default-on since the server
         | is where the resource usage decision matters)
         | 
         | I don't see why WebSockets should benefit from HTTP. Besides
         | the handshake to setup the bidirectional channel, they're a
         | separate protocol. I'll agree that servers should think twice
         | about using them: they necessitate a lack of statelessness &
         | HTTP has plenty of benefits for most web usecases
         | 
         | Still, this is a good article. SSE looks interesting. I host an
         | online card game openEtG, which is far enough from real time
         | that SSE could potentially be a way to reduce having a
         | connection to every user on the site
        
         | bullen wrote:
         | The problem with WebSockets is that hey are:
         | 
         | 1) More complex and binary so you cannot debug them as easily,
         | specially on live and specially if you use HTTPS.
         | 
         | 2) The implementations don't parallelize the processing, with
         | Comet-Stream + SSE you just need to find a application server
         | that has concurrency and you are set to scale on the entire
         | machines cores.
         | 
         | 3) WebSockets still have more problems with Firewalls.
        
       | sb8244 wrote:
       | I can't find any downsides of SSE presented. My experience is
       | that they're nice in theory but the devils in the details. The
       | biggest issue being that you basically need http/2 to make them
       | practical.
        
         | anderspitman wrote:
         | In some cases you might actually be better served sticking with
         | HTTP/1.1 and serving SSE over several domains, to avoid HTTP/2
         | head-of-line blocking.
        
         | bullen wrote:
         | Absolutely not, HTTP/1.1 is the way to make SSE fly:
         | 
         | https://github.com/tinspin/rupy/wiki/Comet-Stream
         | 
         | Old page, search for "event-stream"... Comet-stream is a
         | collection of techniques of which SSE is one.
         | 
         | My experience is that SSE goes through anti-viruses better!
        
           | mwcampbell wrote:
           | > My experience is that SSE goes through anti-viruses better!
           | 
           | Hmm, another commenter says the opposite:
           | 
           | https://news.ycombinator.com/item?id=30313692
        
             | bullen wrote:
             | He just needs to push more data on the reply to force the
             | anti-virus to flush the data. Easy peasy.
        
           | anderspitman wrote:
           | Take this for what it's worth, but I see you share rupy on
           | pretty much every thread that mentions WebSockets, and I
           | click on the link pretty much every time, and I still have
           | basically no idea what it is. Documentation probably isn't
           | your priority at the moment, but even just a couple
           | paragraphs could go a long way.
        
             | ByThyGrace wrote:
             | I had the same impression as you. I want to learn more
             | about fuse but even their "sales pitch" page is in the same
             | tone of "fuse can do a lot" (and that's fine, I'm sold!)
             | except there is very little documentation at the moment.
        
       | kreetx wrote:
       | SSEs had a severe connection limit, something like 4 connections
       | per domain per browser (IIRC), so if you had four tabs open then
       | opening new ones would fail.
        
         | oplav wrote:
         | 6 connections per domain per browser:
         | https://bugs.chromium.org/p/chromium/issues/detail?id=275955
         | 
         | There are some hacks to work around it though.
        
         | coder543 wrote:
         | Browsers also limit the number of websocket connections. But,
         | if you're using HTTP/2, as you should be, then the multiplexing
         | means that you can have effectively unlimited SSE connections
         | through a limited number of TCP connections, and those TCP
         | connections will be shared across tabs.
         | 
         | (There's one person in this thread who is just ridiculously
         | opposed to HTTP/2, but... HTTP/2 has serious benefits. It
         | wasn't developed in a vacuum by people who had no idea what
         | they were doing, and it wasn't developed aimlessly or without
         | real world testing. It is used by pretty much all major
         | websites, and they _absolutely_ wouldn 't use it if HTTP/1.1
         | was better... those major websites exist to serve their
         | customers, not to conspiratorially push an agenda of broken
         | technologies that make the customer experience worse.)
        
           | anderspitman wrote:
           | You can also make your HTTP/1.1 SSE endpoints available on
           | multiple domains and have the client round-robin them.
           | Obviously adds some complexity, but sometimes it's a tradeoff
           | worth making for example if you're on lossy networks and
           | trying to avoid HTTP/2 head-of-line blocking.
        
           | jcheng wrote:
           | > Browsers also limit the number of websocket connections
           | 
           | True but the limit for websockets these days is in the
           | hundreds, as opposed to 6 for regular HTTP requests.
        
             | coder543 wrote:
             | https://stackoverflow.com/questions/26003756/is-there-a-
             | limi...
             | 
             | It appears to be 30 per domain, not "hundreds", at least as
             | of the time this answer was written. I didn't see anything
             | more recent that contradicted this.
             | 
             | In practice, this is unlikely to be problematic unless
             | you're using multiple websockets per page, but the limit of
             | 6 TCP connections is _even less likely_ to be a problem if
             | you're using HTTP /2, since those will be shared across
             | tabs, which isn't the case for the dedicated connection
             | used for each websocket.
        
               | jcheng wrote:
               | It's 255 for Chrome and has been since 2015, 200 for
               | Firefox since longer than that.
               | 
               | https://chromium.googlesource.com/chromium/src/net/+/259a
               | 070...
               | 
               | Agree that it should be _much_ less of a problem with
               | HTTP /2 than HTTP/1.1.
        
       | jshen wrote:
       | Question for those of you who build features on web using things
       | like SSE or web sockets, how do you build those features in
       | native mobile apps?
        
         | johnny22 wrote:
         | isn't that just an event dispatcher?
        
       | mythz wrote:
       | We use SSE for our APIs Server Events feature
       | https://docs.servicestack.net/server-events with C#,
       | JS/TypeScript and Java high-level clients.
       | 
       | It's a beautifully simple & elegant lightweight push events
       | option that works over standard HTTP, the main gotcha for
       | maintaining long-lived connections is that server/clients should
       | implement their own heartbeat to be able to detect & auto
       | reconnect failed connections which was the only reliable way
       | we've found to detect & resolve broken connections.
        
         | dabeeeenster wrote:
         | "the main gotcha for maintaining long-lived connections is that
         | server/clients should implement their own heartbeat to be able
         | to detect & auto reconnect failed connections"
         | 
         | That sounds like a total nightmare!
        
           | ec109685 wrote:
           | Definitely needed. That would be true for all long lived
           | connection protocols in order to detect connection
           | interruptions in a timely fashion.
        
       | ravenstine wrote:
       | I usually use SSEs for personal projects because they are way
       | more simple than WebSockets (not that those aren't also simple)
       | and most of the time my web apps just need to listen for
       | something coming from the server and not bidirectional
       | communication.
        
       | Too wrote:
       | Can someone give a brief summary of how this differs from long
       | polling. It looks very similar except it has a small layer of
       | formalized event/data/id structure on top? Are there any
       | differences in the lower connection layers, or any added support
       | by browsers and proxies given some new headers?
       | 
       | What are the benefits of SSE vs long polling?
        
         | anderspitman wrote:
         | SSE doesn't support binary data. Text only.
        
         | TimWolla wrote:
         | > What are the benefits of SSE vs long polling?
         | 
         | The underlying mechanism effectively is the same: A long
         | running HTTP response stream. However long-polling commonly is
         | implemented by "silence" until an event comes in and then
         | performing another request to wait for the next event, whereas
         | SSE sends you multiple events per request.
        
       | waylandsmithers wrote:
       | I had the pleasure of being forced to use in SSE due to working
       | with a proxy that didn't support websockets.
       | 
       | Personally I think it's a great solution for longer running tasks
       | like "Export your data to CSV" when the client just needs to get
       | an update that it's done and here's the url to download it.
        
       | axiosgunnar wrote:
       | So do I understand correctly that when using SSE, the login
       | cookie of the user is not automatically sent with the SSE request
       | like it is with all normal HTTP requests? And I have to redo auth
       | somehow?
        
         | bastawhiz wrote:
         | It should automatically send first party cookies, though you
         | may need to specify withCredentials.
        
       | ponytech wrote:
       | One problem I had with WebSockets is you can not set custom HTTP
       | headers when opening the connection. I wanted to implement a JWT
       | based authentication in my backend and had to pass the token
       | either as a query parameter or in a cookie.
       | 
       | Anyone knows the rationale behind this limitation?
        
         | charlietran wrote:
         | The workaround/hack is to send your token via the "Sec-
         | WebSocket-Protocol" header, which is the one header you're
         | allowed to set in browser when opening a connection. The catch
         | is that your WebSocket server needs to echo this back on a
         | successful connection.
        
       | TimWolla wrote:
       | > RFC 8441, released on September 2018, tries to fix this
       | limitation by adding support for "Bootstrapping WebSockets with
       | HTTP/2". It has been implemented in Firefox and Chrome. However,
       | as far as I know, no major reverse-proxy implements it.
       | 
       | HAProxy supports RFC 8441 automatically. It's possible to disable
       | it, because support in clients tends to be buggy-ish:
       | https://cbonte.github.io/haproxy-dconv/2.4/configuration.htm...
       | 
       | Generally I can second recommendation of using SSE / long running
       | response streams over WebSockets for the same reasons as the
       | article.
        
       | The_rationalist wrote:
       | for bidi Rsocket is much better than wevsocket, in fact its
       | official support is the best feature of spring boot
        
       | julianlam wrote:
       | This is really interesting! I wonder why it never really took
       | off, whereas websockets via Socket.IO/Engine.io did.
       | 
       | At NodeBB, we ended up relying on websockets for almost
       | everything, which was a mistake. We were using it for simple
       | call-and-response actions, where a proper RESTful API would've
       | been a better (more scalable, better supported, etc.) solution.
       | 
       | In the end, we migrated a large part of our existing socket.io
       | implementation to use plain REST. SSE sounds like the second part
       | of that solution, so we can ditch socket.io completely if we
       | really wanted to.
       | 
       | Very cool!
        
         | shahinghasemi wrote:
         | > At NodeBB, we ended up relying on websockets for almost
         | everything, which was a mistake.
         | 
         | Would you please elaborate on the challenges/disadvantages
         | you've encountered in comparison to REST/HTTP?
        
       | foxbarrington wrote:
       | I'm a huge fan of SSE. In the first chapter of my book Fullstack
       | Node.js I use it for the real-time chat example because it
       | requires almost zero setup. I've also been using SSE on
       | https://rambly.app to handle all the WebRTC signaling so that
       | clients can find new peers. Works great.
        
         | viiralvx wrote:
         | Rambly looks sick, thanks for sharing!
        
       | rough-sea wrote:
       | A complete SSE example in 25 lines on Deno Deploy:
       | https://dash.deno.com/playground/server-sent-events
        
       | pictur wrote:
       | Does SSE offer support for capturing connect/disconnect
       | situations?
        
         | bullen wrote:
         | The TCP stack can give you that info if you are lucky in your
         | topography but generally you cannot rely on this working 100%.
         | 
         | The way I solve it is to send "noop" messages at regular
         | intervals so that the socket write will return -1 and then I
         | know something is off and reconnect.
        
       | rawoke083600 wrote:
       | I like them, they surprisingly easy to use..
       | 
       | One example where i found it to be not the _perfect_ solution was
       | with a web turn-based game.
       | 
       | The SSE was perfect to update gamestate to all clients, but to
       | have great latency from the players point of view whenever the
       | player had to do something, it was via a normal ajax-http call.
       | 
       | Eventually I had to switch to _uglier_ websockets and keep
       | connection open.
       | 
       | Http-keep-alive was that reliable.
        
         | coder543 wrote:
         | With HTTP/2, the browser holds a TCP connection open that has
         | various streams multiplexed on top. One of those streams would
         | be your SSE stream. When the client makes an AJAX call to the
         | server, it would be sent through the already-open HTTP/2
         | connection, so the latency is very comparable to websocket --
         | no new connection is needed, no costly handshakes.
         | 
         | With the downsides of HTTP/1.1 being used with SSE, websockets
         | actually made a lot of sense, but in many ways they were a
         | kludge that was only needed until HTTP/2 came along. As you
         | said, communicating back to the server in response to SSE
         | wasn't great with HTTP/1.1. That's before mentioning the
         | limited number of TCP connections that a browser will allow for
         | any site, so you couldn't use SSE on too many tabs without
         | running out of connections altogether, breaking things.
        
         | johnny22 wrote:
         | I think it comes down to whether your your communication is
         | more oriented towards sending than receiving. If the clients
         | receive way more than they send, then SSE is probably fine, but
         | if it's truly bidirectional then it might not work as well.
        
         | bullen wrote:
         | You just needed to send a "noop" (no operation) message at
         | regular intervals.
        
           | jcelerier wrote:
           | that puts it instantly in the "fired if you ever use it" bin
        
             | Vosporos wrote:
             | Fired for using a keep-alive message???
        
             | notreallyserio wrote:
             | Why's that?
        
       | hishamp wrote:
       | We moved away from WebSockets to SSE, realised it wasn't makings
       | thing any better. In fact, it made things worse, so we switched
       | back to WebSockets again and worked on scaling WebSockets. SSE
       | will work much better for other cases, just didn't work out for
       | our case.
       | 
       | First reason was that it was an array of connections you loop
       | through to broadcast some data. We had around 2000 active
       | connections and needed a less than 1000ms latency, with
       | WebSocket, even though we faced connections drops, client
       | received data on time. But in SSE, it took many seconds to reach
       | some clients, since the data was time critical, WebSocket seemed
       | much easier to scale for our purposes. Another issue was that SSE
       | is like an idea you get done with HTTP APIs, so it doesn't have
       | much support around it like WS. Things like rooms, clientIds etc
       | needed to be managed manually, which was also a quite big task by
       | itself. And a few other minor reasons too combined made us switch
       | back to WS.
       | 
       | I think SSE will suit much better for connections where bulk
       | broadcast is less, like in shared docs editing, showing stuff
       | like "1234 users is watching this product" etc. And keep in mind
       | that all this is coming from a mediocre full stack developer with
       | 3 YOE only, so take it with a grain of salt.
        
         | DaiPlusPlus wrote:
         | Your write-up sounds like your issues with SSE stemmed from the
         | framework/platform/server-stack you're using rather than of any
         | problems inherent in SSE.
         | 
         | I haven't observed any latency or scaling issues with SSE - on
         | the contrary: in my ASP.NET Core projects, running behind IIS
         | (with QUIC enabled), I get better scaling and throughput with
         | SSE compared to raw WebSockets (and still-better when compared
         | to SignalR), though latency is already minimal so I don't think
         | that can be improved upon.
         | 
         | That said, I do prefer using the existing pre-built SignalR
         | libraries (both server-side and client-side: browser and native
         | executables) because the library's design takes away all the
         | drudgery.
        
         | nly wrote:
         | Checkout nchan.io
        
       | pbowyer wrote:
       | There's also the Mercure protocol, built on top of Server-Sent
       | Events: https://mercure.rocks/
        
       | captn3m0 wrote:
       | I think SSE might make a lot of sense for Serverless workloads?
       | You don't have to worry about running a websocket server, any
       | serverless host with HTTP support will do. Long-polling might be
       | costlier though?
        
       | tgv wrote:
       | But SSE is a oneway street, isn't it? The client gets one chance
       | to send days, and that's it? Or is there some way around it?
        
         | jessaustin wrote:
         | Clients can always send normal http messages to the server.
         | Probably not ideal for "bi-directional" traffic, but it's an
         | option in a pinch.
        
       | leeoniya wrote:
       | the biggest drawback with SSE, even when unidirectional comm is
       | sufficient is
       | 
       | > SSE is subject to limitation with regards to the maximum number
       | of open connections. This can be especially painful when opening
       | various tabs as the limit is per browser and set to a very low
       | number (6).
       | 
       | https://ably.com/blog/websockets-vs-sse
       | 
       | SharedWorker could be one way to solve this, but lack of Safari
       | support is a blocker, as usual. https://developer.mozilla.org/en-
       | US/docs/Web/API/SharedWorke...
       | 
       | also, for websockets, there are various libs that handle auto-
       | reconnnects
       | 
       | https://github.com/github/stable-socket
       | 
       | https://github.com/joewalnes/reconnecting-websocket
       | 
       | https://dev.to/jeroendk/how-to-implement-a-random-exponentia...
        
         | coder543 wrote:
         | This isn't a problem with HTTP/2. You can have as many SSE
         | connections as you want across as many tabs as the user wants
         | to use. Browsers multiplex the streams over a handful of shared
         | HTTP/2 connections.
         | 
         | If you're still using HTTP/1.1, then yes, this would be a
         | problem.
        
           | leeoniya wrote:
           | hmmm, you might be right. i wonder what steered me away.
           | maybe each SSE response re-sends headers, which can be larger
           | than the message itself?
           | 
           | maybe it was inability to do broadcast to multiple open sse
           | sockets from nodejs.
           | 
           | i should revisit.
           | 
           | https://medium.com/blogging-greymatter-io/server-sent-
           | events...
        
         | bullen wrote:
         | It used to be 2 sockets per client, so now it's 6?
         | 
         | Well it's a non-problem, if you need more bandwith than one
         | socket in each direction can provide you have much bigger
         | problems than the connection limit; which you can just ignore.
        
           | leeoniya wrote:
           | the problem is multiple tabs. if you have, e.g. a bunch of
           | Grafana dashboards open on multiple screens in different tabs
           | (on same domain), you will exhaust your HTTP connection limit
           | very quickly with SSE.
           | 
           | in most cases this is not a concern, but in _some_ cases it
           | is.
        
             | bullen wrote:
             | Aha, ok yes then you would need to have many subdomains?
             | 
             | Or make your own tab system inside one browser tab.
             | 
             | I can see why that is a problem for some.
        
       | beebeepka wrote:
       | So, what are the downsides to using websockets? They are my go-to
       | solution when I am doing a game, chat, or something else that
       | needs interactivity.
        
         | bullen wrote:
         | See my comment below:
         | https://news.ycombinator.com/item?id=30313403
        
           | herodoturtle wrote:
           | Been reading all your comments on this thread (thank you)
           | with interest.
           | 
           | Can you recommend some resources for learning SSE in depth?
        
             | bullen wrote:
             | I would look at my own app-server:
             | https://github.com/tinspin/rupy
             | 
             | It's not the most well documented but it's the smallest
             | implementation while still being one of the most performant
             | so you can learn more than just SSE.
        
             | mceachen wrote:
             | https://developer.mozilla.org/en-US/docs/Web/API/Server-
             | sent...
        
       | mmzeeman wrote:
       | Did research on SSE a short while ago. Found out that the
       | mimetype "text/event-stream" was blocked by a couple of anti-
       | virus products. So that was a no-go for us.
        
         | bastawhiz wrote:
         | How did you find that out?
        
           | mmzeeman wrote:
           | https://github.com/mmzeeman/mod_sse
        
         | pornel wrote:
         | It's not blocked. It's just that some very badly written
         | proxies can try to buffer the "whole" response, and SSE is
         | technically a never-ending file.
         | 
         | It's possible to detect that, and fall back to long polling.
         | Send an event immediately after opening a new connection, and
         | see if it arrives at the client within a short timeout. If it
         | doesn't, make your server close the connection after every
         | message sent (connection close will make AV let the response
         | through). The client will reconnect automatically.
         | 
         | Or run:                   while(true) alert("antivirus software
         | is worse than malware")
        
         | ronsor wrote:
         | These days I feel like the only way to win against poorly
         | designed antiviruses and firewalls is to--ironically enough--
         | behave like malware and obfuscate what's going on.
        
         | captn3m0 wrote:
         | I was using SSE when they'd just launched (almost a decade ago
         | now) and never faced any AV issues.
        
           | azinman2 wrote:
           | Is that still the case now? How big and broad an audience do
           | you have?
           | 
           | My experience, now a bit dated, is that long polling is the
           | only thing that will work 100% of the time.
        
         | bullen wrote:
         | They don't block it, they cache the response until there is
         | enough data in the buffer... just push more garbage data on the
         | first chunks...
        
       | quickthrower2 wrote:
       | Is it worth upgrading a long polling solution to SSE? Would I see
       | much benefit?
       | 
       | What I mean by that is client sends request, server responds in
       | up to 2 minutes with result or a try again flag. Either way
       | client resends request and then uses response data if provided.
        
         | bullen wrote:
         | Yes, since IE7 is out of the game long-polling is no longer
         | needed.
         | 
         | Comet-stream and SSE will save you alot of bandwidth and CPU!!!
        
           | layer8 wrote:
           | What is particular about IE7? According to
           | https://caniuse.com/eventsource, SSE is unsupported through
           | IE11.
        
       | jFriedensreich wrote:
       | this is what i have been telling people for years, but its hard
       | to get the word out there. usually every dev just reflexes
       | without thinking to websockets when anything realtime or push
       | related comes up.
        
       | steve76 wrote:
        
       ___________________________________________________________________
       (page generated 2022-02-12 23:00 UTC)