[HN Gopher] Woe be unto you for using a WebSocket
       ___________________________________________________________________
        
       Woe be unto you for using a WebSocket
        
       Author : mathgladiator
       Score  : 133 points
       Date   : 2021-12-22 16:28 UTC (6 hours ago)
        
 (HTM) web link (www.adama-lang.org)
 (TXT) w3m dump (www.adama-lang.org)
        
       | bri3d wrote:
       | I think this conflates a very specific paradigm for using
       | WebSockets (state synchronization with a stateful "server") with
       | WebSockets as a technology.
       | 
       | At the end of the day, WebSockets are just, well, sockets, with a
       | goofy HTTP "upgrade" handshake and some framing on top of them.
       | You could implement the exact same request/response model as in
       | an HTTP based service over a WebSocket if you wanted to.
       | 
       | Stateful services are a tradeoff whether you use a WebSocket or
       | not.
       | 
       | Reading through here, I think what you're trying to build is a
       | synchronized stateful distributed system where state management
       | becomes more transparent to the engineer, not only across backend
       | services but also between the browser and the service side - this
       | is well tread ground and a huge problem, but an interesting one
       | to take on nonetheless. "WebSockets" are a red herring and just
       | an implementation detail.
        
         | mathgladiator wrote:
         | You're right. The key thing is the spectrum of freedom induced
         | by the library/framework. For example, if use something like
         | PHP then you live in a prison of the request lifecycle.
         | Sometimes the prison is socially enforced by not having shared
         | state between requests within a process.
         | 
         | There is nothing special about websockets, but they do confer a
         | freedom and responsibility.
        
       | vikR0001 wrote:
       | Just use Meteor and/or Apollo. They have all this stuff figured
       | out.
       | 
       | https://www.meteor.com/
       | 
       | https://www.apollographql.com/
        
       | cultofmetatron wrote:
       | come to phoenix/elixir land. Channels are amazing and the new
       | views system allows you to seamlessly sync state to a frontend
       | using websockets with almost no javascript
        
         | mathgladiator wrote:
         | Perhaps I will.
         | 
         | I'm thinking about how I position Adama for both Jamstack and
         | as a reactive data-store (which could feed phoenix/elixer
         | land). I intend to change my marketing away from the
         | "programming language" aspect and more towards "reactive data
         | store".
        
         | Zealotux wrote:
         | My side-project relies heavily on WS, I'm currently using
         | Node.js and it's alright but learning Elixir is my goal during
         | these holidays. Any resource to share to get started? I don't
         | know much about Elixir except it's perfect for such use-cases.
        
           | dqv wrote:
           | I got pretty far in the beginning just by reading the docs on
           | Phoenix channels [0]. I was learning Phoenix and ReactJS at
           | the same time and got a pretty simple Redux thunk that
           | interacted with Phoenix Channels in a few days. I'm not sure
           | if that was the optimal way to do it, but it was really cool
           | interacting with the application from IEx (elixir shell).
           | 
           | You might find an interesting (albeit more complex) entry
           | point by interacting with Phoenix Channels from your Node.js
           | app using the Channels Node.js client [1] and within the
           | frontend itself.
           | 
           | [0]: https://hexdocs.pm/phoenix/channels.html [1]:
           | https://www.npmjs.com/package/phoenix-channels
        
           | lawn wrote:
           | The book Real-Time Phoenix is good for designing realtime
           | systems.
           | 
           | For a good introduction to Elixir, I loved Elixir in Action
           | which also covers OTP.
           | 
           | If you want a good Phoenix resource, the book Programming
           | Phoenix is good.
           | 
           | Finally, the docs in Elixir and Phoenix are great.
        
           | sb8244 wrote:
           | I wrote Real-Time Phoenix and it goes into pretty much
           | everything that I hit when shipping decently large real-time
           | Channel application into production. Like, the basics of "I
           | don't know what a Channel is" into the nuance of how it's a
           | PITA to deploy WS-based applications due to load balancers
           | and long-lived connections.
           | 
           | The new LiveView book is great if you're interested in going
           | fully into Elixir (server/client basically). I use LiveView
           | for my product and it's great.
        
           | b5n wrote:
           | Being already familiar with FP I was able to jump right into
           | elixir after running through learn you some erlang. Erlang
           | and elixir are very similar, and you get the bonus of
           | learning a bit about OTP, BEAM, and the underlying
           | philosophy. There's a ton of resources after that, and the
           | docs are easy to use and understand.
           | 
           | https://learnyousomeerlang.com/
        
           | cultofmetatron wrote:
           | I was a nodejs programmer for almost 8 years before I hopped
           | to elixir. A lot of it was motivated btw elixir's realtime
           | system and concurrency.
           | 
           | One of the issues with nodejs is that you're stuck to one
           | process which is single threaded. IE: you're stuck to one
           | core. Yes there are systems like clustering which relies on a
           | master process spawning slave processes and communicating
           | over a bridge but in my experience, its pretty janky.
           | 
           | You're making a great move by trying out elixir. It solves a
           | lot of the issues I ran into working with nodejs.
           | Immutability is standard and if you compare two maps, it
           | automatically does a deep evaluation of all the values in
           | each tree.
           | 
           | The killer feature however is liveview. Its what meteor
           | WISHES it could be. realtime server push of html to the dom
           | and teh ability to have the frontend trigger events on the
           | backend in a process thats isolated to that specific user.
           | Its a game changer.
           | 
           | Anyways, if you're looking for resources to learn. pragprog
           | has a bunch of great books on elixir. Thats how I got
           | started.
        
         | callamdelaney wrote:
         | Channels are basically websockets and only supported inside
         | Phoenix as far as I can tell..
        
           | cultofmetatron wrote:
           | its more than just webockets. Its a prototcol built on web-
           | sockets that also include keepalive and long-polling
           | fallback.
           | 
           | You could in theory replicate the protocol in another stack
           | but its more than that. Elixir is uniquely suited to
           | websocket applications. Since a websocket is persistent, you
           | need a process on your end that handles that. Elixir is
           | excellent at creating lightweight threads for managing these
           | connections. Out of the box, you can easily support a few
           | thousand connections on a single server.
           | 
           | I know because we did it at my startup. channels powers our
           | entire realtime sync system and its yet to be a bottleneck.
           | It more or less works out of the box without issue. Its
           | almost boring level reliable.
        
             | callamdelaney wrote:
             | Elixir inherits those properties from the Beam VM it shares
             | with Erlang - both languages are effectively great for this
             | WS/Channels use case - but Channels seems unhelpful unless
             | you're already using phoenix. I can't see that it can be
             | used in say Erlang.
        
               | sb8244 wrote:
               | Channels are really just a protocol, but that protocol is
               | implemented in Elixir (Phoenix) and so isn't available
               | elsewhere.
               | 
               | I think that the important question is "why does this
               | protocol exist?" Most likely, you'll end up solving
               | similar problems as to why Channels exist in the first
               | place. So from a protocol perspective, it's nice that
               | some problems are solved for you.
        
               | prophesi wrote:
               | May not fit your use-case, but you can create an umbrella
               | project with both an Erlang app and an Elixir/Phoenix
               | app, whereby the latter's capable of calling functions in
               | the former.
        
       | hattmall wrote:
       | I've never seen websockets accomplish anything that push with
       | long polling didn't do more effective and efficiently. I think
       | they are a technology that missed their time, the CPU / power
       | savings are generally non-existent and the minimal bandwidth
       | savings are frequently negated by the need to add in redundancy
       | and checks.
        
         | anderspitman wrote:
         | If SSE supported binary data I might agree with you. I think
         | WebSockets have their place, but are overused. I definitely
         | agree long polling should be implemented first and then only
         | add WS if you've measured that you need it. You're probably
         | going to need to implement polling anyway for clients to catch
         | up after disconnect.
        
       | eska wrote:
       | I'm confused. Just because you use request response doesn't mean
       | you don't have state in your page. And sure, your connection can
       | drop, but your requests can also fail. Protocol versioning is
       | required, but that is true for any protocol ever, also request
       | response. And what's this about wanting to outsource all state
       | and everything requires a database as soon as it has state? Which
       | one does mspaint.exe use? And if using a load balancer or proxy
       | somehow leaks through then something really messed up is going
       | on. In pubsub, just like REST, one doesn't care who sent the
       | data. I'm confused.
        
         | mathgladiator wrote:
         | Sorry about that. Yes, those are required but you have more
         | freedom to go wrong in more severe ways.
         | 
         | Mspaint uses the file system at command of the user. Something
         | that I didn't mention (which I will I'm a revision) I'd that
         | the server is being run by another person with their own
         | deployment schedule. So, we generally like to excise state ASAP
         | to a durable medium since process state is volatile.
        
       | rglover wrote:
       | Make sure you handle disconnects/reconnects, leverage query
       | params to pass state (ideally limited), sync/scale via Redis
       | pubsub, and assume that the websocket will fail so always have
       | some sort of fallback/redundacy. Ideally think of websockets like
       | sprinkles on ice cream.
       | 
       | Shameless plug: https://cheatcode.co/courses/how-to-implement-
       | real-time-data...
        
       | [deleted]
        
       | halpert wrote:
        
       | pshc wrote:
       | On the plus side, once you get a good websocket steady state
       | going, the efficiency and latency benefits are nice compared to
       | HTTP1 polling.
       | 
       | Maybe not that big of an advantage anymore with HTTP2 popping
       | off.
        
       | FZambia wrote:
       | Every time I read criticism of WebSockets it reminds me about
       | WebSuckets (https://speakerdeck.com/3rdeden/websuckets)
       | presentation :)
       | 
       | I am the author of Centrifugo server
       | (https://github.com/centrifugal/centrifugo) - where the main
       | protocol is WebSocket. Agree with many points in post - and if
       | there is a chance to build sth without replacing stateless HTTP
       | to persistent WebSocket (or EventSource, HTTP-streaming, raw TCP
       | etc) - then definitely better to go without persistent
       | connections.
       | 
       | But there are many tasks where WebSockets simply shine - by
       | providing a better UX, providing a more interactive content,
       | instant information/feedback. This is important to keep - even if
       | underlying stack is complicated enough. Not every system need to
       | scale to many machines (ex. multiplayer games with limited number
       | of players), corporate apps not really struggle from massive
       | reconnect scenarios (since number of concurrent users is pretty
       | small), and so on. So WebSockets are definitely fine for certain
       | scenarios IMO.
       | 
       | I described some problems with WebSockets Centrifugo solves in
       | this blog post - https://centrifugal.dev/blog/2020/11/12/scaling-
       | websocket. I don't want to say there are no problems, I want to
       | say that WebSockets are fine in general and we can do some things
       | to deal with things mentioned in the OP's post.
        
         | zemo wrote:
         | > Not every system need to scale to many machines (ex.
         | multiplayer games with limited number of players)
         | 
         | the author writes a websocket board game server. Most, if not
         | all, of these complaints read like the author isn't
         | partitioning the connections by game.
        
       | jeroenhd wrote:
       | I've only professionally used WebSockets with Spring Boot and
       | React and I must say: they're perfectly fine?
       | 
       | That is, if you use WS to simply asynchronously communicate
       | events and do out-of-band message passing, they operate quickly,
       | easily and efficiently. I wouldn't use them to send binary blobs
       | back and forth or rely on them to keep a perfect state match, but
       | for notifications and push events they're a delight to work with.
       | Plus, their long-term connectivity gives them an edge above plain
       | HTTP because you can actually store a little state in sockets
       | rather than deriving state from session cookies and the like.
       | 
       | Yes, WebSockets don't fit well within the traditional "one
       | request, one response, one operation" workflow that the web was
       | built upon, but that model is arguably one of the worst problems
       | you encounter when you use HTTP for web applications (not
       | websites, though; for websites, HTTP works perfectly!). Most
       | backend frameworks have layers upon layers of processing and
       | securty mitigations exactly because HTTP has no inherent state
       | 
       | WebSockets aren't some magical protocol that will make all of
       | your problems go away but if used efficiently, they can be a huge
       | benefit to many web applications. I've never used (or even heard
       | of) Adama, so I can totally believe that websockets are a
       | terrible match for whatever use case this language has, but that
       | doesn't mean they deserve to get such a bad rep. You just have to
       | be aware of your limitations when you use them, the same way you
       | need to be aware of the limitations of HTTP.
        
         | superice wrote:
         | Absolutely right, until you have multiple instances of backends
         | you need to deal with and synchronize, which is a pain in the
         | behind. The OPs main issue seems to be with that problem, which
         | is the tough component of using something stateful like
         | websockets anyways. The impedance mismatch of 'something
         | happened in the database' to 'send event over websocket' is
         | painful in a multi backend instance environment.
         | 
         | Case in point: dossier locking in the product we both worked
         | on. Hi Jeroen! Always nice to find an old colleague on here :)
        
           | jeroenhd wrote:
           | Ha, hey there! Nice username :)
           | 
           | You're totally right, of course; for shared states between
           | different backend instances you'll need a different solution,
           | like database locking or complicated inter-backend API calls,
           | or even a separate (set of) microservice(s) to deal purely
           | with websockets while other backend operate on the database.
           | That way you can apply scaling without data consistency
           | issues, if you want to go for a _really_ (unnecessarily)
           | complicated solution.
           | 
           | It all depends on your problem space. If you want to make a
           | little icon go green on a forum because someone commented on
           | your post, I think websockets are perfect, much better than
           | the long-lived HTTP polls of yore.
           | 
           | I think the OP is using websockets to synchronize game state
           | across different clients, which can be quite tricky even
           | without having to deal with scaling or asynchronous
           | connections. You can use websockets for that, but manual HTTP
           | syncs/websocket reconnects after a period of radio silence
           | would not go amiss. Hell, if it's real-time games this is
           | about, you might even want a custom protocol on top of WebRTC
           | to get complete control over data ad state with much better
           | performance.
        
       | TameAntelope wrote:
       | I kludged together subscription support for our GraphQL stack,
       | and it's super scary because the product people see it working
       | and are like, "this is awesome!" but sometimes it doesn't totally
       | work, and I don't think they realize how hard it would be to,
       | "just make it work all the time".
       | 
       | I want a "real" non-kludge solution, but it's hard to convince
       | someone they need to give you money to throw away something that
       | "works", from their perspective.
        
       | phtrivier wrote:
       | For all the mean things I could say about the language and it's
       | ecosystem, this is one area where elixir/phoenix/channels shine.
        
       | oautholaf wrote:
       | I worked for a while on a well-known product that used (and
       | perhaps still uses) WebSockets for its core feature. I very much
       | agree with the bulk of the arguments made in this blog post.
       | 
       | In particular, I found this:
       | 
       | - Our well-known cloud hosting provider's networks would
       | occasionally (a few times a year) disconnect all long-lived TCP
       | sockets in an availability zone in unison. That is, an incident
       | that had no SLA promise would cause a large swath of our
       | customers to reconnect all at once.
       | 
       | - On a smaller scale, but more frequently: office networks of
       | large customers would do the same thing.
       | 
       | - Some customers had network equipment that capped the length of
       | time of that a TCP connection could remain open, interfering with
       | the preferred operation
       | 
       | - And of course, unless you do not want to upgrade your server
       | software, you must at some point restart your servers (and again,
       | your cloud hosting provider likely has no SLA on the uptime of an
       | individual machine)
       | 
       | - As is pointed out in the article, a TCP connection can cease to
       | transmit data even though it has not closed. So attention must be
       | paid to this.
       | 
       | If you use WebSockets, you must make reconnects be completely
       | free in the common case and you must employ people who are
       | willing to become deeply knowledgeable in how TCP works.
       | 
       | WebSockets can be a tremendously powerful tool to help in making
       | a great product, but in general they are almost always will add
       | more complexity and toil with lower reliability.
       | 
       | (edited typos)
        
         | inopinatus wrote:
         | None of this is particular to websockets, and in addition:
         | 
         | > you must employ people who are willing to become deeply
         | knowledgeable in how TCP works
         | 
         | You already needed that for your HTTP based application; it's a
         | fundamental of networked computing. Developers skipping out on
         | mechanical sympathy are often duds, in my experience.
        
         | vlovich123 wrote:
         | > - Our well-known cloud hosting provider's networks would
         | occasionally (a few times a year) disconnect all long-lived TCP
         | sockets in an availability zone in unison. That is, an incident
         | that had no SLA promise would cause a large swath of our
         | customers to reconnect all at once.
         | 
         | I'm kind of surprised that it was that infrequent. I would
         | expect software upgrades should cause long-lived sockets to
         | reset...
        
           | inopinatus wrote:
           | or a scale-up of an ELB
        
         | xyzzy_plugh wrote:
         | > disconnect all long-lived TCP sockets in an availability zone
         | in unison
         | 
         | I don't know what this means, but it sounds ridiculous. This
         | would cause havoc with any sort of persistent tunnel or
         | stateful connection, such as most database clients. Do you
         | perhaps mean this just happens at ingress? That is much more
         | believable and not as big of a deal.
         | 
         | > office networks of large customers would do the same thing.
         | 
         | Sounds like a personal problem. In all seriousness, your
         | clients should handly any sort of network disconnect
         | gracefully. It's foolish to assume TCP connections are durable,
         | or to assume that you won't be hit by a thundering herd.
         | 
         | Maybe I'm old fashioned but TCP hasn't changed much over the
         | years, none of these problems are novel to me, it's well-
         | trodden ground and there are many simple techniques to building
         | durable clients.
         | 
         | Also, all of the things you mention also affect plain old HTTP,
         | especially HTTP2. There shouldn't be a significant difference
         | in how you treat them, other than the fact you cannot assume
         | they're all short lived connections.
        
           | oautholaf wrote:
           | Most applications written using HTTP, in my experience, do
           | not have deep dependencies on the longevity of the HTTP2
           | connection. In my experience, TCP connections for HTTP2 are
           | typically terminated at your load balancer or similar. So
           | reconnections here happen completely unseen by either the
           | client application in the field or the servers where the
           | business logic is.
           | 
           | For us -- and I think this is common -- the persistent
           | WebSocket connection allowed a set of assumptions around the
           | shared state of the client and server that would have to be
           | re-negotiated when reconnecting. The fact that this
           | renegotiation was non-trivial was a major driver in selecting
           | WebSockets in the first place. With HTTP, regardless of HTTP2
           | or QUIC, your application protocol very much is set up to re-
           | negotiate things on a per-request basis. And so the issues I
           | list don't tend to affect HTTP-based applications.
        
             | xyzzy_plugh wrote:
             | > the persistent WebSocket connection allowed a set of
             | assumptions around the shared state of the client and
             | server that would have to be re-negotiated when
             | reconnecting. The fact that this renegotiation was non-
             | trivial was a major driver in selecting WebSockets in the
             | first place. With HTTP, regardless of HTTP2 or QUIC, your
             | application protocol very much is set up to re-negotiate
             | things on a per-request basis. And so the issues I list
             | don't tend to affect HTTP-based applications.
             | 
             | I think this describes a poor choice in technology. There's
             | no silver bullet here, and it sounds like you made a lot of
             | questionable tradeoffs. Assuming that "session" state
             | persists beyond the lifetime of either the client or the
             | server is generally problematic. It's always easier for one
             | party to be stateless, but you can become stateful for the
             | duration of the transaction.
             | 
             | Shared state is best used as communications optimization,
             | and maybe sometimes useful for security reasons.
        
           | tyingq wrote:
           | >Sounds like a personal problem. In all seriousness, your
           | clients should handly any sort of network disconnect
           | gracefully
           | 
           | That can be complex. Corporate MITM filtering boxes,
           | "intrusion detection" appliances, firewalls, etc, can just
           | decide to drop NAT entries, drop packets, break MTU path
           | discovery, etc. Yes, there are things you can do. But then
           | customers restart/reload when things don't happen instantly,
           | etc. I don't know that there's a simple playbook.
        
         | bri3d wrote:
         | I built several large enterprise products over WebSockets. I
         | didn't find it that bad.
         | 
         | Office networks that either blocked or killed WebSockets were
         | annoying. For some customers they were a non-starter in the
         | early 2010s, but by 2016 or so this seemed to be resolved.
         | 
         | Avoiding thundering herd on reconnect is a very explored
         | problem and wasn't too bad.
         | 
         | We would see mass TCP issues from time to time as well, but
         | they were pretty much no-ops as they would just trigger a
         | timeout and reconnect the next time the user performed an
         | operation. We would send an ACK back instantly (prior to
         | execution) for any client requested operation, so if we didn't
         | see the ACK within a fairly tight window, the client could
         | proactively reap the WebSocket and try again - customers didn't
         | have to wait long to learn a connection was alive and unclosed.
         | 
         | > If you use WebSockets, you must make reconnects be completely
         | free in the common case
         | 
         | I agree with this, or at least "close to completely free." But
         | in a normal web application you also need to make latency and
         | failed requests "close to completely free" as well or your
         | application will also die along with the network. This is the
         | point I make in my sibling comment - I think distributed state
         | management is a hard problem, but WebSockets are just a layer
         | on top of that, not a solution or cause of the problem.
         | 
         | > you must employ people who are willing to become deeply
         | knowledgeable in how TCP works.
         | 
         | I think this is true insofar as you probably want a TCP expert
         | somewhere in your organization to start with, but we never
         | found this particularly complicated. Understanding that the
         | connection isn't trustworthy (that is, when it says it's open,
         | that doesn't mean it works) is the only important fundamental
         | for most engineers to be able to work with WebSockets.
        
           | anderspitman wrote:
           | > Office networks that either blocked or killed WebSockets
           | were annoying
           | 
           | Curious how did they detect WS usage? Were you running on
           | HTTP or did they just kill any long-lived TCP connection?
           | Root certs?
        
             | bri3d wrote:
             | No, we always ran on TLS. There were a few classes of
             | these:
             | 
             | * Filtering MITM application firewall solutions which
             | installed a new trusted root CA on employee machines and
             | looked at the raw traffic. These would usually be
             | configured to wholesale kill the connection when they saw
             | an UPGRADE because the filtering solutions couldn't
             | understand the traffic format and they were considered a
             | security risk.
             | 
             | * Oldschool HTTP proxy based systems which would blow up
             | when CONNECT was kept alive for very long.
             | 
             | * Firewalls which killed long-lived TCP connections just at
             | the TCP level. The worst here were where there was a
             | mismatch somewhere and we never got a FIN. But again,
             | because we had a rapid expectation for an acknowledgement,
             | we could detect and reap these pretty quickly.
             | 
             | We also tried running WebSockets on a different port for
             | awhile, which was not a good idea as many organizations
             | only allowed 443.
        
       | Waterluvian wrote:
       | I use WebSockets for robots to communicate real-time state with a
       | web UI. They're the only option and they're fine.
       | 
       | I get that this article is more focused on a narrow perspective
       | of the technology. But of course you can make silly use of any
       | technology.
        
         | eska wrote:
         | I also implemented MQTT for industrial machines to publish data
         | to a broker. It was trivial to create a web UI that subscribed
         | to that broker via MQTT over Websockets. But I noticed that
         | colleagues had this impression that MQTT cannot be used on the
         | web, so they wanted to build a conversion from MQTT to
         | SignalR.. a quick search would've cleared it up, but they were
         | so sure for some reason. After I showed them the demo they just
         | went with MQTT as well.
        
       | jvanderbot wrote:
       | Author: in this doc, headers are paragraph topic sentences, not
       | bookmarks for disjoint ideas.
       | 
       | And they are nonsensical. "Problem: Bumps in the night#". Oh,
       | thanks, let me bookmark that for easy sharing.
        
       | PaulDavisThe1st wrote:
       | We used WebSockets to build a web-based front end for Ardour, a
       | native cross-platform DAW, and didn't encounter any of these
       | issues. Part of that is because the protocol was already defined
       | (Open Sound Control aka OSC) and used over non-web-sockets
       | already. But as others have noted, most of the problems cited in
       | TFA come from the design goals, not the use of websockets.
        
       | swagasaurus-rex wrote:
       | For the very reasons listed in the article, I built:
       | 
       | https://github.com/siriusastrebe/jsynchronous
       | 
       | a library for keeping a javascript variables synchronized between
       | Node.js servers and clients.
       | 
       | Websockets work great for message passing but it struggles with
       | data structures more complicated than what JSON can represent.
       | Jsynchronous syncs any javascript object or array with
       | arbitrarily deep nesting and full support for circular data
       | structures.
       | 
       | If a computer goes to sleep, or disconnects, websocket
       | connections (and their underlying TCP connections) get reset so
       | you lose any data sent while a computer is unavailable. This is
       | catastrophic for state-management if it's left unhandled.
       | Jsynchronous will re-send any data clients are missing and
       | reconstructs the shared state.
       | 
       | There's also a history mode that lets you rewind to past states.
        
         | adamddev1 wrote:
         | Very, very nice! I might use that! Just gotta wrap it a nice
         | React hook.
        
         | anderspitman wrote:
         | Very cool. I tried something similar once. Have you gone down
         | the differential/compressed update rabbit hole yet?
        
           | swagasaurus-rex wrote:
           | Right now jsynchronous message passes using custom encoding
           | in JSON which keeps simple changes as small as an HTTP
           | header, but with byte level encoding I think this could be
           | halved.
           | 
           | Some compression on top would probably do wonders for huge
           | volumes of changes, though more browsers are supporting
           | compression on the websocket level.
           | 
           | I'm not familiar with the name differential update. Instead
           | of passing potentially large states back and forth,
           | Jsynchronous numbers each change to your synchronized data
           | and shares these changes with all connected clients. This is
           | called Event Sourcing, and it enables jsynchronous to rewind
           | to previous states by running the changes from start to any
           | intermediate state.
        
       | mgamache wrote:
       | Using Blazor (.net). It's been mostly a good experience. Fast UI
       | updates, good programming model.
        
         | mwattsun wrote:
         | I've been looking at it lately and the SignalR tech it uses.
         | Very nice. My cursory Google research indicates a server using
         | it can handle about 3000 users, which is not many, but for my
         | purposes is fine. Blazor makes it completely optional, which I
         | proved to myself by doing client side Blazor (dot net wasm)
         | only and using an Apache server instead of IIS with ASP.NET.
         | 
         | https://en.wikipedia.org/wiki/SignalR
        
           | mgamache wrote:
           | Right, with .net core 6 the runtime wasm is much smaller.
           | SignalR can be scaled if you need to, but for most sites 3000
           | concurrent users is plenty.
        
         | wvenable wrote:
         | We're migrating to server-side Blazor because of the good
         | experience yet all of the things mentioned in this article are
         | a concern for using this technology. A few things, especially
         | around deployment and maintenance, are significantly less good
         | when your clients are always connected. I'm currently trying to
         | figure out mitigations.
        
       | thisrobot wrote:
       | Full disclosure I work at MSFT and on the fluid framework.
       | 
       | If you are interested in this you may also be interested in the
       | fluid framework, https://github.com/microsoft/FluidFramework
       | 
       | We use websockets and solve a lot of the state management problem
       | called out here by keeping very little state on the server
       | itself. The primary thing on server is a monotonically increasing
       | integer we use to stamp messages, this gives us total order
       | broadcast which we then build upon:
       | https://en.m.wikipedia.org/wiki/Atomic_broadcast
       | 
       | Here are some code pointers if you want to take a look:
       | 
       | The map package is a decent place to look for how we leverage
       | total order broadcast to keep clients in sync in our distributed
       | data structures:
       | https://github.com/microsoft/FluidFramework/blob/main/packag...
       | 
       | The deltamanger in the container-loader package is where we
       | manage the websocket. It also hits storage to give the rest of
       | the system a continuous, ordered stream of events:
       | 
       | https://github.com/microsoft/FluidFramework/blob/main/packag...
       | 
       | The main server logic is in the Alfred and Deli lambdas. Alfred
       | sits on the socket and dumps message into Kafka. Deli sits on the
       | Kafka queue, stamps messages, the puts them on another queue for
       | Alfred's to broadcast:
       | https://github.com/microsoft/FluidFramework/tree/main/server...
        
       | Philip-J-Fry wrote:
       | You can turn websockets into a flawless request/response with
       | async/await included on like 20 lines of JavaScript. I do it all
       | the time.
       | 
       | Generate an ID, make a request, store the promise resolve/reject
       | in a map (js object). Your onmessage handler looks up the promise
       | based on the ID and resolves the promise.
       | 
       | Add a few more tiny features like messaging and broadcasting
       | streams and you've got both request/response and push messaging
       | over a single websocket.
       | 
       | It's pretty neat in my opinion, saves having to mix HTTP and
       | websockets for a lot of things.
        
         | anderspitman wrote:
         | It is neat. I've gone down this path[0]. But you find yourself
         | essentially re-implementing HTTP, and losing things like
         | backpressure. Sometimes it's what you need, but I try to be
         | cautious before jumping to WS these days.
         | 
         | [0]: https://iobio.io/2019/06/12/introducing-fibridge/
        
       | winrid wrote:
       | WebSockets are great when used in _addition to_ polling. This
       | way, you can design a system that doesn 't result in missed
       | events. Example: have a /events?fromTS=123 endpoint.
       | 
       | At FastComments - we do both. We use WS, and then poll the event
       | log when required (like on reconnect, etc).
       | 
       | Products that can get away with just polling should. In a lot of
       | scenarios you can just offload a lot of the work to companies
       | like OneSignal or UrbanAirship, too.
       | 
       | If you're going to use WS and host the server yourself, make sure
       | you have plans for being able to shard or scale it horizontally
       | to handle herds.
       | 
       | It was hard for us to not use websockets, since like 70% of our
       | customers pick us for being a "live" solution for live events
       | etc.
        
         | anderspitman wrote:
         | Is it really worth the extra effort for WS over long polling at
         | that point though? Especially if you're re-using the TCP
         | connection it seems like the overhead would be minimal and the
         | latency only slightly increased.
        
           | winrid wrote:
           | Sorry for the misunderstanding, but I don't mean WS over long
           | polling. I mean WS _in addition to_ polling, not long
           | polling. Use websockets, but also expose an API to get the
           | same events by specifying a timestamp. This way the websocket
           | server implementation can be much simpler, and the client
           | just has to call the API to  "catch up" on missed events on
           | reconnect.
           | 
           | You can also use this API for integrations, and your
           | clients/consumers will thank you. For example, our third
           | party integrations use the event log to sync back to their
           | own data stores. They probably call this every hour, or once
           | a day. You wouldn't want to use websockets with PHP apps like
           | WordPress.
        
       | te_chris wrote:
       | Worth looking at Elixir Phoenix Channels if you're wanting to use
       | sockets. Handle a lot of the messy stuff for you.
       | 
       | https://hexdocs.pm/phoenix/channels.html
        
       | anderspitman wrote:
       | A few years ago I was more inclined to use WebSockets. They're
       | undeniably cool. But as implemented in browsers (thanks to the
       | asynchronous nature of JavaScript) they offer no mechanism for
       | backpressure, and it's pretty trivial to freeze both Chrome and
       | Firefox sending in a loop if you have a fast upload connection.
       | 
       | I designed a small protocol[0] to solve this (and a few other
       | handy features) which we use at work[1]. A more robust option to
       | solve similar problems is RSocket[3].
       | 
       | More recently I've been working on a reverse proxy[2], and
       | realized how much of a special case WebSockets is to implement.
       | Maybe I'm just lazy and don't want to implement WS in
       | boringproxy, but these days I advocate using plain HTTP whenever
       | you can get away with it. Server Sent Events on HTTP/1.1 is
       | hamstrung by the browser connection limit, but HTTP/2 solves
       | this, and HTTP/3 solves HTTP/2's head of line blocking problems.
       | 
       | Also, as mentioned in the article, I try to prefer polling. This
       | was discussed recently on HN[4].
       | 
       | [0]: https://github.com/omnistreams
       | 
       | [1]: https://iobio.io/2019/06/12/introducing-fibridge/
       | 
       | [2]: https://boringproxy.io/
       | 
       | [3]: https://rsocket.io/
       | 
       | [4]: https://news.ycombinator.com/item?id=27823109
        
       | loevborg wrote:
       | My advice:
       | 
       | * Make push updates optional. If no push connection can be
       | established, fall back to polling. You can start by implementing
       | polling only and add push later.
       | 
       | * Use websockets only for server-to-client communication.
       | Messages from the client are sent via regular HTTP requests.
       | 
       | * Keep no meaningful state on the server. That includes TCP
       | connection state. You should be able to kill all your ec2
       | instances and re-spawn them without interrupting service.
       | 
       | * Use request/response for all logic on the server. All your code
       | should be able to run in an AWS lambda.
       | 
       | * Use a channel/subscription paradigm so client can connect to
       | streams they're interested in
       | 
       | * Instead of rolling your own websocket server, use a hosted
       | service like pusher.com or ably.com. They do all the heavy
       | lifting for you (like keeping thousands of TCP connections open)
       | and provide a request/response style interface for your server to
       | send messages to connected clients
        
       | badrabbit wrote:
       | There is this particular app I have to use for work which relies
       | heavily on web sockets. It works great so long as your latency is
       | good. But as soon as your latency is over some threshold the
       | sheer volume of websocket requests compounds and it becomes
       | unusable. Normal sites just load slower, they don't fail entirely
       | like this.
       | 
       | I guess it goes without saying but devs really need to test their
       | apps under unfavorable conditions.
        
       | austincheney wrote:
       | The biggest challenge when migrating from HTTP to any kind of
       | stream is the loss of callback on response, because there is no
       | request/response. There is only push. That means your messaging
       | and message handling becomes far more complex to compensate.
       | 
       | The article mentions that your socket could drop. This isn't
       | critical so long as you have HTTP as a redundancy.
       | 
       | For any kind of application making use of micro services I
       | strongly recommend migrating to a socket first transmission
       | scheme because it is an insane performance improvement. Also it
       | means the added complexity to handle message management makes
       | your application more durable in the face of any type of
       | transmission instability. The durability means that your
       | application is less error prone AND it is ready for migration to
       | other protocols in the future with almost no refactoring.
        
       | spicybright wrote:
       | All of these issues could be solved well by a decent library. Or
       | even just basic well thought out abstractions.
       | 
       | I've written a few before from "scratch" myself to decent
       | success. I don't think there's anything inherent with sockets
       | that make it impossible to use well. I mean, we've been using
       | sockets since the beginning of the internet.
       | 
       | You can write the same article for literally any technology
       | that's complicated to use without abstractions.
        
         | mathgladiator wrote:
         | That's the core thing is the discover of well thought out
         | abstractions for a specific domain. I glossed over a lot of the
         | specific details, but I iterated the pitfalls that I have seen
         | and how I'm thinking about the abstractions I'm using.
        
       | tbeseda wrote:
       | Archive link with https https://archive.li/R8Nxi
        
       | woodruffw wrote:
       | Just in case the author is listening, I'll play the grammar nazi:
       | it's "woe unto," not "woe onto."
        
         | mathgladiator wrote:
         | I'll fix when I return to my computer. Thanks
        
         | dang wrote:
         | I was just wondering if anyone had pointed that out. Fixed
         | above.
         | 
         | Edit: it probably should be "woe unto". From the King James
         | Bible:                 54  woe unto       24  woe to        2
         | woe be unto        1  woe be to
         | 
         | but "woe be unto" is in there so I guess it's legit enough.
        
       | mmzeeman wrote:
       | You don't have to design a new protocol. There is an open
       | protocol which works nice for this use case. It can handle
       | dropping connections, has a nice routing mechanism, it scales
       | pretty well, has different QoS levels, pub/sub, request/response.
       | That protocol is... MQTT v5!
       | 
       | Personally I'm surprised it is not used more often by web devs.
        
         | thatswrong0 wrote:
         | We use this at my place of employment and it's generally OK
         | except for dealing with reconnects. Also pub/sub
         | request/response was not nearly as smooth as we had hoped and
         | eventually we reverted back to HTTP
        
           | mmzeeman wrote:
           | We have build a nice support library for it.
           | https://github.com/cotonic/cotonic. It helps that our backend
           | is Erlang. https://github.com/zotonic/zotonic.
        
         | [deleted]
        
       ___________________________________________________________________
       (page generated 2021-12-22 23:00 UTC)