[HN Gopher] The WebSocket Handbook
___________________________________________________________________
The WebSocket Handbook
Author : AlexTDiaconu
Score : 210 points
Date : 2022-01-11 16:09 UTC (6 hours ago)
(HTM) web link (ably.com)
(TXT) w3m dump (ably.com)
| e1g wrote:
| In case the email collection form gets hugged to death, here's a
| mirror
| https://web.archive.org/web/20220111162712/https://files.abl...
|
| In our experience, many enterprise networks/vpns/firewalls still
| break websocket connections even when using wss, and it should
| not be used as the only communication channel even if you target
| evergreen browsers.
| app4soft wrote:
| Thank You for mirror!
| paddybyers wrote:
| Disclaimer: I work for Ably. I agree in principle, so the
| libraries that handle websockets and also fallback transports
| using comet (eg SocketIO) are still widely used for that
| reason, and the commercial pub/sub service providers generally
| also support comet fallbacks. However, we now find that it is
| really very rare that clients are unable to use wss.
| e1g wrote:
| WSS breaking is _surprisingly_ common for clusters of our
| enterprise users, to the order of 5-10%. Specifically, when
| business users connect through security networks like
| Zscaler, often their employers will MITM all connections
| (similar to how AdGuard works) but in a way that breaks WSS.
| We have rigorous monitoring for both frontend and backend,
| and can trace these failures with accuracy - consistently,
| both the frontend and the ingress firewall think that the
| other one cancelled the connection attempt, so some network
| hop in-between did that. Every other network connection
| during that time works as expected (long polling /SSE over
| H2), but WSS get interrupted and sometimes can't reconnect.
| We still love the aliveness of web sockets, but have to
| architect data fetching in a way that doesn't depend on them
| working.
| matt_oriordan wrote:
| That's surprising to hear, we definitely don't see anywhere
| near the order of 5-10%, at best on order of magnitude
| less.
|
| Out of interest, what geography and industries are you
| operating in where you see such a high rate of
| incompatibiltiy?
|
| Matt, Ably co-founder
| e1g wrote:
| China and LATAM are definitely overrepresented. We deal
| with conglomerates and manufacturers, so it's vaguely
| industrial + heavy industry, but all these users are
| corporate folks using standard-issue BigCo laptops
| (almost certainly loaded with standard "security" layers
| from a dozen different vendors, making detailed diagnosis
| nearly impossible for us as a SaaS provider).
| matt_oriordan wrote:
| Thanks for the explanation, useful to know.
| hwers wrote:
| Anyone know of any examples of cool cases where websockets have
| been used? (Maybe other than games.) I feel like in most cases I
| see them used the latency gained is basically added back with
| bloat in other parts.
| matt_oriordan wrote:
| Our customers use Ably across such a diverse set of use cases,
| but here's a few:
|
| 1. Sports events streaming live updates (see
| https://ausopen.com/live-scores, we are streaming live scores
| for the Tennis Australian Open right now). Companies like
| Toyota even use us to facilitate engineers tweaking the
| performance characteristics of their cars in realtime remotely.
|
| 2. Edtech - we have numerous customers using us to drive live
| classroom environments, think shared white boards,
| collaborative tests, presence, teacher engagement. You may have
| used Codewars in the past, that uses Ably under the hood for
| example, https://www.codewars.com/.
|
| 3. Live screen sharing and collaborative applications. You may
| have used the amazing Tuple.app, that uses Ably under the hood
| https://tuple.app/.
|
| 4. Collaborative and live web and mobile SaaS applications,
| where changes need to occur concurrently, notifications need to
| be presented, and other realtime updates are needed in the
| interface. You've probably heard of Hubspot, they use Ably
| under the hood to power their collaborative and live features,
| https://hubspot.com
|
| 5. Developer infrastructure and platforms that need realtime
| capabilities at scale. You have probably come across Split, the
| leading feature flag company backed by Atlassian and Microsoft.
| They use Ably under the hood to power billions of feature flag
| updates in realtime each month. https://www.split.io/
|
| 6. Financial market data - typically streaming updates to
| thousands or millions of subscribers with very low latency, and
| sometimes using features like Deltas
| (https://ably.com/documentation/realtime/channels/channel-
| par...) to keep bandwidth & latency as low as possible.
|
| I could keep going, but I hope that gives you the idea,
| realtime is not just for Christmas or for Games :)
|
| Matt, co-founder of ably.com
| JSdev1 wrote:
| I just launched this site with websockets:
| https://hackernews.pro Websockets used for updating
| Story/Comment data, and User presence
| matt_oriordan wrote:
| Feel free to sign up for an Ably account and we'll help
| support your project with a community package, we love what
| you're doing!
| [deleted]
| pcthrowaway wrote:
| Crypto exchanges almost exclusively use websockets for pushing
| out real-time price and orderbook changes. They provide rest
| apis also, but with limits that prevent bots from keeping the
| data as close to in sync as possible, which is important for
| algorithmic trading.
|
| Whether this qualifies as a 'cool' case is probably subjective,
| but it is important in practice.
|
| I'm not sure if it's as widespread, but many exchanges use
| websockets in the front-end to make the same data available to
| the site users without frequent polling.
| twic wrote:
| We use them for a variety of intranet realtime dashboard type
| things. Both user-facing production UI, where users are looking
| at screens covered with dozens of dashboards all updating
| several times a second, and developer-facing monitoring.
|
| The client-side code is generally very simple. A dashboard
| opens a websocket and attaches a handler which parses the
| message (all our payloads are JSON), then routes the update to
| the right bit of the UI. We wrote a thin wrapper round the
| browser websocket API to handle disconnections. We wrote
| server-side libraries to support our patterns of use.
|
| I initially did a bunch of developer-facing dashboards using
| server-sent events, because they're slightly easier to work
| with. However, websockets have a significant advantage over
| SSE: you can have a lot more of them open at once. Browsers
| will limit you to a few (six?) connections per origin,
| including long-lived SSE connections, whereas you can have
| dozens or hundreds of websockets open [1]. If you are serving
| lots of different dashboards off a single server, you rapidly
| get to the point where this matters!
|
| [1] https://stackoverflow.com/questions/26003756/is-there-a-
| limi...
| paxys wrote:
| Pretty much every app that has a real-time communication
| component relies heavily on websockets. Slack and other
| messaging apps, document editors, financial tickers, sports
| sites.
| jkarneges wrote:
| A bunch of things we (Fanout) have seen as a WebSocket
| provider, other than games: shared document editing, field
| worker management, live voting, parking space tracking, feature
| flags, sports updates, home security, ridesharing, financial
| tickers, notifications, news feeds, exercise classes, realtime
| audio analysis, and remote controls.
| thisisjofrank wrote:
| These are great examples. I'd add delivery tracking/any
| geolocation tracking works great with websockets. And of
| course chat messaging.
| hombre_fatal wrote:
| wrt gaming, there was a websocket game of spaceships flying
| around posted to HN a few times where the clients open two
| websocket connections to iirc get around tcp head of queue
| blocking. Maybe they were sending round robin updates across
| them.
|
| Couldn't find the Show HN just now but searching "subspace"
| comments might reveal it ("this reminds me of subspace"). I
| always wanted to look more into the approach.
| acdibble wrote:
| Just this past weekend, I created a service for transferring
| files that is built on websockets (https://qr.dibble.codes /
| https://github.com/acdibble/qr-transfer). It's still rough and
| very MVP, but it's functional.
|
| My use case was I wanted to transfer a PDF to an Android-based
| tablet but in the moment didn't want to log into my email. I
| couldn't think of any quick, easy, and cross-platform solutions
| so I decided to write the service.
|
| It's built on socket.io which is a godsend for websockets
| because it automatically handles so much grunt work and your
| app just works.
| scurvy_steve wrote:
| I have an app based around some long running resource intensive
| processes that run on scalable microservices. So you click a
| button and may have to wait 5+ minutes before you get a
| response. Websockets let you do notifications and make
| everything async. They've served me well for request/response
| that might take 3-30 minutes.
| austincheney wrote:
| I wrote a document explaining how to implement your own web
| socket service:
| https://github.com/prettydiff/wisdom/blob/master/websocket_s...
|
| Implementing your own service logic is incredibly helpful in the
| cases where you have multiple sockets to manage and custom logic
| associated with identity, reestablishment, custom data handling,
| and so forth. There are features in the protocol that aren't used
| in the browser, for example, and allow for custom scaling.
|
| Here are my learnings about web sockets:
|
| * They are session oriented so that means both end points have to
| agree to connect. That mitigates many security risks associated
| with HTTP traffic.
|
| * Web socket messages cannot be interleaved. In 99% of cases this
| isn't an issue, because control frames unrelated to a web socket
| message can occur anywhere without interruption. This becomes a
| problem if you are transfer a large file that takes a substantial
| amount of transfer time. All other messages must wait in a queue,
| which means long delayed microservice status updates or you just
| break things.
|
| * Web sockets are so much faster to process than HTTP. A web
| socket is primitive. There is no roundtrip (request/response), no
| headers, and no additional negotiation. I reduced some test
| automation in my personal application from 45 seconds to 7
| seconds by fully converting from HTTP to web sockets for
| messaging.
|
| * Reliance on web sockets simplifies so much of a service
| oriented application. I used to rely upon callbacks to HTTP
| responses to verify message completion and perform next step
| actions in an application. Instead I am switching to specific
| messaging for everything. A response is a specific message when
| the responding machine is ready. This eliminates response
| timeouts, flattens the architecture, and eases service testing by
| moving all messaging concerns to a single listener as opposed to
| listening for responses versus requests from other machines.
|
| * Since web sockets are session oriented they are potentially
| more fragile than HTTP. If the pipe drops you have to reestablish
| the connection before sending/receiving service messages.
| cookiengineer wrote:
| A couple months ago I posted the "Implementer's guide to
| WebSockets" that I wrote, but it seemingly got shadowbanned. [1]
|
| I wrote the guide with example code for people wanting to know
| how to implement the complete WS13 protocol from scratch, so you
| can try it out, fiddle around and modify it to your needs.
|
| The guide is more in-depth and assumes that the reader is willing
| to read the RFC when they're stuck :)
|
| [1] https://cookie.engineer/weblog/articles/implementers-
| guide-t...
| clone1018 wrote:
| We use WebSockets in two regards: handling live page updates via
| Phoenix Live View for users (eg: real time chat messages, viewer
| count, etc) and as a transport medium for our real time API. The
| former is very easy to handle because for the most part users are
| navigating around pages which can terminate the ws connection and
| creates a new one (though most of the times not). The advantages
| Live View provides us is not having to write duplicated logic in
| the client & server, and instead just push data to users and
| their browser automatically reflects the changes.
|
| However the latter use offers very powerful benefits with some
| difficult downsides. On the positives side you get a "real time"
| API to work with, and you can handle events as they happen and
| send updates back to them. In some cases our API users can even
| respond to a chat message faster than we can!
|
| Since WebSockets are virtually just a transport, it's up to you
| to write a protocol for handling heartbeats, authentication, and
| communication. In addition when you have a horizontally scaled
| service it can make balancing the WebSocket connections a bit
| more challenging since they are long lived. Deployments are even
| more inconvenient since (in our case) we disconnect the WebSocket
| consumers whenever a server is restarted for the update. It can
| also be difficult to fully measure and understand how many
| WebSocket connections you have open, and how many resources they
| are consuming. It's important to really push down the number of
| computations you are doing for users who are subscribed to the
| same topics so that when you send out 10,000 updates with the
| same message it's just the text being sent, not 10,000 DB queries
| :D.
| lvass wrote:
| >we disconnect the WebSocket consumers whenever a server is
| restarted for the update
|
| Isn't avoiding this the main selling point for BEAM? As in
| Erlang: the movie. Can't that be done with websockets?
| sb8244 wrote:
| You could totally do this with BEAM, via hot swapping. The
| WebSocket processes don't really change, it's the
| implementation of what happens when messages comes in that
| changes. So you'd setup your hot swap with this in mind. (The
| connection processes stay connected and the behavior module
| is swapped out?)
|
| However, hot swapping is not super common in practice. Mainly
| because it's added complexity that most people can live
| without.
| clone1018 wrote:
| Right, this is the comment I was going to make as well.
| It's certainly possible, but there's tradeoffs (mainly
| around complexity) to code hot-swapping. We haven't
| implemented it because restarting servers to upgrade code
| helps everyone prepare for when servers go down for
| unexpected reasons, or so I like to think :P!
| ddoolin wrote:
| I think your last paragraph is a good point for using services
| like the OP. All three of the examples you mentioned are
| already solved. Granted, you're buying into their paradigm
| particularly regarding communication model but that's a small
| price to pay for the upsides.
|
| Disclaimer: we've been using Ably for years and their service
| and reliability has been outstanding, and we have worked
| closely with their engineers and I've found their expertise to
| be above what you may expect from experience with other
| company's support personnel.
| matt_oriordan wrote:
| Thanks ddoolin. I am not sure which company you are, but I
| appreciate your comments and even more happy to hear you feel
| we're doing a fantastic job! You've sort of encapsulated why
| we exist: we know software engineers can build and run all
| sorts of things on their own i.e. we're not the only option
| from open source solutions to custom builds. However, we
| built Ably to be the easiest, most scalable, and reliable
| realtime option which for developers that removes complexity
| and helps them manage costs as they grow (pay for what you
| use).
|
| Matt, co-founder at Ably
| mwcampbell wrote:
| I'm generally reluctant to add dependencies on third-party
| services such as Ably in the core application, because that
| would add another barrier to providing an on-prem deployment
| option, or even allowing a customer to deploy on their own
| AWS infrastructure instead of ours. I'm actually
| contemplating this decision right now for a new product.
| matt_oriordan wrote:
| I am surprised to hear about on-prem deploys when the
| direction of travel is towards serverless/cloud solutions
| that don't require orchestration. Out of interest, why is
| on-prem so important for your use case? Separately, I'd be
| interested in how you'd view that decision if there was a
| less scalable but mostly fully functioning open source
| version of the third-party service you could deploy if you
| needed to?
|
| Matt, co-founder of Ably
| mwcampbell wrote:
| For one of my company's products, we're already working
| with a security-sensitive customer on a deployment on
| their own AWS infrastructure (in their own VPC). This
| customer wouldn't be comfortable using our public cloud
| deployment unless we get a SOC2 certification or similar.
| For the product I'm developing now, some potential
| customers will definitely want to keep it physically
| located within their corporate network. That's all I can
| say publicly.
|
| If there was a less scalable, but still mostly
| functioning open-source substitute for Ably, then I'd be
| way more comfortable using Ably in the main public cloud
| deployment.
| matt_oriordan wrote:
| I understand the SOC2 requirement, which is why we're
| SOC2 compliant. A long and painful process, but one that
| has opened up opportunities like the one you said would
| otherwise require an on-prem installation. We have in
| fact also got some VPN-like links (AWS PrivateLink) with
| customers who are particularly sensitive to security and
| data leaving their network, and that coupled with SOC2
| has made it possible.
|
| > If there was a less scalable, but still mostly
| functioning open-source substitute for Ably, then I'd be
| way more comfortable using Ably in the main public cloud
| deployment.
|
| Thanks for the feedback, I will pass on to the product
| team!
| [deleted]
| nurettin wrote:
| Sorry to butt in like this, but cloud is just one
| direction, not the direction. Pretty much any company
| that values their privacy and independence will want on-
| prem. This should not come as a surprise to anyone.
| mathgladiator wrote:
| This is one reason I'm making my up and coming SaaS
| entirely open source, so you can run a clone in any
| environment: http://www.adama-lang.org/
| nlitened wrote:
| > it can make balancing the WebSocket connections a bit more
| challenging since they are long lived. Deployments are even
| more inconvenient since (in our case) we disconnect the
| WebSocket consumers whenever a server is restarted
|
| May I suggest that the solution could be to design your WS
| protocol to be reconnect-friendly, like the Phoenix LiveView
| protocol? Maybe make a protocol which assumes and expects that
| a connection may be dropped by any side at any time, with
| robust context-restoration API such as "full snapshot" or "all
| updates since event ID"
| nly wrote:
| Anyone considering augmenting an existing web service with
| Websockets should take look at the Nchan nginx plugin.
|
| https://nchan.io/
| twic wrote:
| I use websockets quite a lot, for real-time dashboard kind of
| purposes.
|
| The one thing i really wish websockets had is some kind of
| application-level acknowledgement or backpressure.
|
| At the server end, you're blasting out messages to the client,
| but you have no idea if it is keeping up with them. Most of the
| time, it will be, but if there is a sudden spike of activity,
| suddenly all your dashboards are going wild, and the client may
| start to struggle. At that point, you want to be able to shed
| some load - delay messages a bit, then drop any message which
| gets superseded (eg if "reactor core temperature is 1050K" is
| buffered and you get "reactor core temperature is 1100K", you can
| drop the former). To do that, you need feedback about how far the
| client has got with processing messages.
|
| You can build a feedback mechanism like this into your
| application protocol on top of websockets easily enough. But you
| probably want to do that from the start, or else you will, like
| me, one day look around and realise that retrofitting it to all
| your dashboards is a monumental effort.
|
| The RSocket protocol might be a good start - it provides reactive
| streams semantics, and has a binding to websockets:
|
| https://rsocket.io/guides/rsocket-js
| klabb3 wrote:
| There should be a law for message passing systems, which says
| that everyone will eventually want ordered delivery,
| multiplexing (with priorities), exactly-once semantics,
| acknowledgements and backpressure. (Maybe more?)
|
| I'm pretty convinced all these popular features could be
| layered in a reasonable way that could be implemented in most
| messaging systems, and have standardized semantics and
| conventions. It seems like every time, we're reinventing the
| wheel, and half the time people talk over one-another because
| we're using inexact language.
|
| Basically, what I want is a "message passing a la carte" paper.
| Groxx wrote:
| "Every sufficiently-complex system eventually includes a
| badly-implemented email / lisp / kafka (/zmq/etc)"
|
| Something like a combination of Greenspun's Tenth Rule[1] and
| Zawinski's Law[2]. Plus whatever would include your queueing
| system of choice.
|
| Though honestly I've seen more bad queues than emails or
| lisps. By an order of magnitude or two.
|
| [1]: https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule
| [2]:
| https://en.wikipedia.org/wiki/Jamie_Zawinski#Zawinski's_Law
| anderspitman wrote:
| I built omnistreams[0] primarily because of the lack of
| backpressure in browser WebSockets (lots of background
| information in that README). It's what fibridge[1] is built on.
| We've been using it in production for over 2 years, but I never
| ended up trying to push omnistreams as a thing. I believe the
| Rust implementation is actually behind the spec a bit, and the
| spec itself probably needs some work.
|
| At the end of the day I think RSocket is probably the way to go
| for most people, though the simplicity of omnistreams is still
| appealing to me.
|
| [0]: https://github.com/omnistreams/omnistreams-spec
|
| [1]: https://iobio.io/2019/06/12/introducing-fibridge/
| gfd wrote:
| I don't know anything about websockets, but isn't it over tcp?
| Meaning if the client isn't keeping up, their buffer should be
| full and the server should be blocked from sending more until
| it drains (unless it's queuing the messages somewhere else?).
| Or is that not how tcp backpressure works?
| twic wrote:
| It is, but since you don't control the receive buffer size in
| the browser, or the TCP window size (or, with many web
| frameworks, the socket buffer size in the server!), you can't
| rely on socket buffers giving you timely feedback. By the
| time the server's send buffer fills, there is already masses
| of stale data buffered in between you and the client.
|
| In my apps i do indeed detect the socket buffers filling,
| just as you suggest, but pretty much only as a way of
| detecting completely wedged clients.
| dmm wrote:
| TCP provides backpressure but depending on it to provide
| backpressure over the internet will greatly increase latency,
| in my experience.
|
| In one application I was streaming jpeg frames over a
| websocket and by the time the server application experienced
| backpressure there were 10s of seconds of messages buffered
| between the server and client. So the message rate would
| eventually settle into a rate the connection could sustain
| but messages would take 10+ seconds to reach the client.
| PaulDavisThe1st wrote:
| Can anyone explain why using websockets with anything other than
| a webstack is so much hard than using regular ol' POSIX sockets,
| given that at some level websockets live right alongside a UDP or
| TCP socket? When we looked around for a library to use in Ardour
| to add websocket support, the choices were slim and none of them
| provided an API as simple as the one for UDP/TCP sockets.
| keithwinstein wrote:
| I think it mostly has to do with:
|
| 1) the large "implementation surface" of three components
| (TLS+HTTP+WebSocket), each of which by itself requires an API
| more complicated, if provided by a userspace library, than a
| kernel-provided TCP socket, and maybe
|
| 2) the fact that non-Web servers are rare enough, and
| WebSockets are still recent enough, that no "standard" library
| has emerged and had its edges honed down over time to support
| multiple applications, especially when the current era and
| funders of open source are probably less incentivized to create
| application-independent libraries than in earlier eras where
| "let's work together to create a free OS with minimal effort"
| was a larger share of the driving forces.
|
| - With TLS you can certainly link with OpenSSL, but the API is
| more complicated than a kernel-provided TCP socket, and
| async/nonblocking TLS requires an API _much_ more complicated.
| TLS sometimes requires a write in response to a read, and to do
| that in an apparently nonblocking fashion either (a) the
| application needs to include callsites back into library in its
| event loop to tell the library when the underlying socket is
| writeable just in case the library had something buffered it
| was hoping to write, (b) the library needs to run its own
| thread that blocks on the underlying socket, or (c) the library
| can only be used with languages that support async behavior in
| a more composable way, which is not C. None of those are good
| options.
|
| - Parsing the incoming HTTP request is tricky and there's no
| "standard choice" for this either, e.g. a library that's been
| distributed in Debian/RedHat/Homebrew for >10 years and is
| depended-on by a bunch of applications.
|
| - The WebSocket protocol requires that a server write a pong in
| response to an incoming ping. As with TLS, this means a
| nonblocking implementation requires a thread or integration
| with the application's event loop, but it's arguably even worse
| because WebSocket wants the server to respond _soon_ to a ping.
| (By contrast, TLS-on-TCP is mostly designed so that an app can
| ignore the read or write direction as long as it wants.) So you
| don 't just need to possibly queue up that pong and later call
| into the library when the socket becomes writeable; you need to
| make sure no other event is going to run or block for a long
| time in the meantime.
|
| So I think the comparison here may not be, "Why isn't there a
| library that provides an API for WebSockets that's almost as
| simple as a kernel-provided TCP socket?" (where the kernel
| basically runs its own thread and does the async work behind
| the scenes), but maybe more like, "Why isn't there a user-space
| library that implements QUIC [or nonblocking TLS, or user-space
| TCP] with a simple API?"
|
| We have implemented a nonblocking C++ WebSocket/TLS server in
| the cleanest fashion we could (https://github.com/stanford-
| stagecast/audio/tree/main/src/ht...), also for a low-latency
| audio project, but it's still a ton of code and has to make its
| own assumptions/demands on how it gets invoked. If you wanted
| to _adopt_ a WebSocket implementation into Ardour, I 'd be
| happy to help you make that happen, but it sounds like you very
| reasonably were looking to outsource this to a library where
| your application isn't the only user.
| PaulDavisThe1st wrote:
| Thanks for that very clear and informative answer.
|
| We ended up using libwebsockets and it's fine. It runs in its
| own thread and the rest of the code doesn't have to care much
| about it. It would have been nice to just use the socket
| directly from liblo (OSC library), but the current
| arrangement seems perfectly OK.
| Scaless wrote:
| websockets unfortunately have to start at the HTTP layer and
| negotiate down to the TCP wrapper layer, so you need at least a
| partial HTTP stack and everything else that involves to get
| there. This complicates things a lot. It's like stuffing a
| turkey, cooking it, then throwing away the meat to just eat the
| stuffing.
|
| In my experience, Boost Beast[1] is the easiest library to just
| get going with but you have to deal with all the Boost-isms
| that comes with. libwebsockets is the 'standard' C
| implementation but unless you know the websocket RFC front to
| back it's quite difficult to work with and has a lot of foot-
| guns.
|
| [1]
| https://www.boost.org/doc/libs/1_78_0/libs/beast/example/web...
| mathgladiator wrote:
| It's related to what you can buy versus build. When you use a
| WebSocket, there may not be a great solution that fits your
| need. If you use just HTTP, then there is a wealth of options
| available to you.
|
| Fundamentally, there is nothing special about a WebSocket over
| a socket rather than a special handshake, some framing, and the
| layering within an existing HTTP server. The problem is that
| the market of developers is vastly different. If you are a
| systems person, then chances are good you know sockets
| decently. If you are a typical web-dev, then the chances are
| not so great and its easy to make a mess that is then exposed
| to the world.
|
| I've mentored teams, and the key challenge isn't technical but
| education on all the gotchas.
| gfd wrote:
| Does anyone know when to choose http2 vs websockets?
| AlexTDiaconu wrote:
| Hi HN! I'm Alex, and I've been researching and writing about
| WebSockets for a while now. I'm the author of the recently
| released WebSocket Handbook. AMA about the WebSocket tech, the
| realtime web, Ably or anything related to Liverpool FC.
| friendlydog wrote:
| What is the right way to handle authentication over web
| sockets?
| AlexTDiaconu wrote:
| As with REST APIs, you'd want to be able to authenticate to a
| websocket-based API using either basic auth, or a bearer
| token-based auth scheme. Unfortunately, the browser websocket
| API doesn't allow you to specify arbitrary headers in the
| websocket request, so it's typical instead to have
| credentials supplied via a query param (such as "accessToken"
| for a bearer token) in the wss request.
| capableweb wrote:
| > so it's typical instead to have credentials supplied via
| a query param (such as "accessToken" for a bearer token) in
| the wss request.
|
| If someone ends up actually doing this in a production
| system, remember to not to log the accessToken if you're
| logging full paths/URIs somewhere, as query params usually
| is a part of that type of logging.
| matt_oriordan wrote:
| Yup, true, although tokens should be ephemeral so less of
| a risk. Authenticating inline over the Websocket
| connection is valid too, but it does expose the socket
| connections to slightly more surface area of attack i.e.
| if you pass in a token as a param, the Websocket request
| can be rejected immediately. If however you authenticate
| after establishing a Websocket connection, then there is
| an attack vector where you simply open Websocket
| connections and never authenticate. Of course timeouts
| can be used to disconnect rogue actors, but it is a
| consideration.
|
| Matt, Ably co-founder
| z3t4 wrote:
| If I understand correctly, websockets is a thin layer on TCP
| that does buffer data so that the application get the whole
| message instead of chunks. I recommend using wss to secure
| the websocket so that it can't be hijacked, then you don't
| need to send a token in each message and can do an
| application layer handshake once. Basically the first websock
| message from the client would be an authentication message
| with a password, token or what not.
| syspec wrote:
| Yeah this is the technique I've also used.
|
| The first websocket message is the original request, which
| will have the users cookies / headers where your session
| information / bearer token should live.
| JSdev1 wrote:
| It's the same thing as HTTP. Websocket starts off as an HTTP
| request with cookies, headers etc. Use those just like HTTP
| to authenticate, and your Websocket server should pass the
| user data to the websocket object
| latch wrote:
| Don't have access to the headers from JS.
|
| Best solution might be to generate a short-lived one-time-
| use ticket and pass it in the querystring.
| twic wrote:
| If you make a normal HTTP request first, the server can
| issue a standard HTTP cookie to the client. That cookie
| will then be included when the browser makes the
| websocket request.
|
| However, websockets are not subject to the same-origin
| policy, so this exposes you to CSRF [1]. To protect
| against that, you should check the Origin header on the
| server side.
|
| [1] https://christian-
| schneider.net/CrossSiteWebSocketHijacking....
| simonkagedal wrote:
| Cookies will be forwarded though, or..?
| mathgladiator wrote:
| It's a good introduction, and it's a good document to introduce
| the problems induced by WebSockets (which Ably can come in an
| solve at scale).
|
| I recently wrote about the Woes of Websocket: http://www.adama-
| lang.org/blog/woe-of-websocket with an errata based on HN
| feedback: http://www.adama-lang.org/blog/more-websocket-woe
|
| The depth of this topic is very interesting, and I'm excited as
| I'm building some of the final pieces for my SaaS (which could
| compete with Ably).
| lelanthran wrote:
| > or anything related to Liverpool FC.
|
| Do people still watch football?
|
| What are the viewership numbers for Liverpool FC?
|
| Does Man United still matter?
|
| :-)
| stichers wrote:
| Man Utd never mattered. Source: City supporter.
| httgp wrote:
| Is Ably playing with WebTransport? If it moves up from its
| current trial status, how do you see that changing Ably's core?
| matt_oriordan wrote:
| We are monitoring it closely and super excited about what
| WebTransport will provide, which is both a more reliable and
| in many cases more performant transport. However, much like
| WebSockets, it's still quite low level and only provides a
| basic communication protocol. As such, like we have done with
| SSE, HTTP, Websockets and MQTT, our service focusses on what
| developers can enable on top of these lower level transports,
| such as presence, deltas, history of streams, limitless scale
| and fan-out of data, and the list goes on
| https://ably.com/platform.
|
| When WebTransport reaches prime time, I'm confident we'll be
| supporting it.
| Ostrogodsky wrote:
| Why does Klopp love to abuse referees and then play dumb?
| superasn wrote:
| Hi! I want to create a web app like Google docs where multiple
| users can collaborate in real time to edit the document
| together (using a special link like gdocs generate). I want to
| save the docs in a MySQL db (no firebase)
|
| My questions are:
|
| 1) Since multiple people are working together how does one
| manage conflicts, i.e. 2 people sending different edits
| simultaneously.
|
| 2) If one clients gets disconnected (4g) and then reconnects
| later how does it sync the changes it made during it was
| offline?
|
| I recently watched this RAFT presentation (1) and I think I
| would need to use something like this?
|
| What other alternatives are viable?
|
| Also can I make it happen using just PHP, Javascript and MySQL?
|
| Thanks
|
| (1) http://thesecretlivesofdata.com/raft/
| born-jre wrote:
| https://en.wikipedia.org/wiki/Conflict-
| free_replicated_data_...
| https://en.wikipedia.org/wiki/Operational_transformation
|
| ofcourse u will need websocket to sync changes.
| hammersmith wrote:
| Have a look at https://m-ld.org/ , its a CRDT implementation
| that's all Javascript. it could help
| matt_oriordan wrote:
| Yup, and it supports Ably too, see
| https://js.m-ld.org/#ably-remotes!
|
| Matt, Ably co-founder
| jkarneges wrote:
| I made a document editing demo here:
| https://github.com/fanout/editor
|
| It uses operational transformations ("OT") to manage
| conflicts, and it saves the data in MySQL. Technically any
| Django DB backend will work for storage, but the public demo
| instance uses MySQL.
|
| One of the reasons I made this thing was to show that
| realtime apps don't need to require heavy frameworks or
| unusual databases. And it loads super fast.
|
| I don't think you need Raft if you have a central database
| storing the document. You could also consider using CRDTs
| instead of OT, which may be more powerful but also more
| challenging to develop.
| mathgladiator wrote:
| CRDT solve a part of your problem, and an important
| consideration is whether or not you want off-line editing. If
| you don't need off-line editing, then a WebSocket can do it.
|
| I'm actually using my project to build a collaborative IDE
| (designer like Figma): http://www.adama-lang.org/
|
| I'm going to be launching it as a SaaS soon so people can
| spin up a new back-end without managing an infrastructure.
| AlexTDiaconu wrote:
| Big question! It deserves its own blog post haha.
|
| CRDTs can be the answer. We actually wrote about them
| recently (https://ably.com/blog/crdts-distributed-data-
| consistency-cha...), and there is more coming soon as our
| Chief Of Scientist and his team are researching CRDTs and
| building demos!
| iratewizard wrote:
| HN is generally reserved for interesting articles. Not self
| promoting your services with a cookie cutter email harvester for
| your drip campaign.
| aparsons wrote:
| I bit and got the book, hoping for something interesting. It's
| more or less the documentation on MDN or a WS library docs
| rephrased.
|
| Finally, after 60 pages of docs I can Google, there's a section
| called "Scaling Websockets", which is an interesting and
| challenging topic.
|
| Turns out it's one paragraph long, saying - "Yeah it's hard.
| You should consider using Ably. Next book will cover it."
|
| Shameful.
| AlexTDiaconu wrote:
| Hey Aparsons, thanks for your feedback. As mentioned in the
| post, the Handbook is not finished and we'll continue to
| evolve, adding more chapters, meat to the current chapters,
| and we have other ideas like exercises.
|
| It's good that you are interested in Scaling WebSockets,
| because that is the chapter I am writing now! I hope to get
| it live in a couple of weeks, once it is I can send you the
| new version.
| Raminj95 wrote:
| Thank you for taking the time to confirm my suspicion,
| greatly appreciated!
| chalas_r wrote:
| Mercure is an alternative to WebSocket that is especially useful
| for REST/GraphQL APIs. It's a protocol that builds on HTTP and
| Server-Sent Events thus is supported out of the box by browsers,
| mobile apps and IoT clients, and it doesn't suffer from most
| WebSocket limitations (e.g. header/cookie based authorization
| works):
|
| https://mercure.rocks
| crummy wrote:
| > it doesn't suffer from most WebSocket limitations (e.g.
| header/cookie based authorization works)
|
| Don't WS connections send headers? What's the limitation here?
| arendtio wrote:
| Does someone know, why Websockets are sometimes considered a
| security risk and blocked by corporate firewalls, even when the
| rest of the website is considered to be trustworthy?
| paxys wrote:
| Before going all-in on websockets I'd like to caution people to
| thoroughly consider the server-side scaling challenges that come
| with it.
|
| HTTP servers have already solved traffic management, load
| balancing, scaling up and down, zero downtime deployments, A/B
| tests and experimentation and lots more to such a degree that we
| don't have to even think about them anymore. All of these
| problems come to the forefront again when you have to scale
| websocket connections beyond a single server.
| mathgladiator wrote:
| I'm going all-in on WebSockets, but I've also seen how to solve
| all those problems at massive scale. You're right that these
| challenges are hard, and I don't believe we have an ideal
| shared offering yet.
|
| We have a cultural challenge of how to manifest the opportunity
| and benefits presented by context rich communication over the
| entrenched ideology of statelessness and HTTP.
| rglover wrote:
| There's a (relatively) easy trick for this: Redis pubsub.
|
| When a message comes into an instance, you push it to Redis and
| have all of your other instances subscribed to it. Messages
| sync in real-time and the experience is transparent.
|
| I teach the technique here: https://cheatcode.co/courses/how-
| to-implement-real-time-data...
| Supermancho wrote:
| To be a bit clearer, you don't want to push websocket
| messages per se; eg auth negotiation or info requests. You do
| want to pubsub out conditioned messages that are generated by
| any given instance for the purpose of broadcast; eg "userX
| connected" or "userX said Y".
| smaddock wrote:
| It's probably worth mentioning that WebTransport just shipped in
| Chrome 97 (2022-01-04), which seems to be a worthy successor to
| WebSockets [0]. It allows for reliable and unreliable modes which
| is a problem for games using WebSockets, among other things.
|
| [0] https://web.dev/webtransport/
| matsemann wrote:
| Is this a new standard, or yet another thing Google is pushing
| and everyone else have to implement?
| vulcan01 wrote:
| Linked in OP: https://w3c.github.io/webtransport/
|
| It's a proposal, 2 editors are from Google the other one is
| from Microsoft.
| capableweb wrote:
| Only Chrome so far it seems. Firefox's position:
|
| > We are generally in support of a mechanism that addresses the
| use cases implied by this solution document. While major
| questions remain open at this time -- notably, multiplexing,
| the API surface, and available statistics -- we think that
| prototyping the proposed solution as details become more firm
| would be worthwhile. We would like see the new WebSocketStream
| and WebTransport stream APIs to be developed in concert with
| each other, so as to share as much design as possible.
|
| https://mozilla.github.io/standards-positions/
|
| Unclear what the WebKit (Safari) folks think, based on
| https://lists.webkit.org/pipermail/webkit-dev/2021-September...
| that has no replies.
|
| Microsoft is just doing whatever Chrome is doing with Edge, so
| I guess it'll appear there sooner or later, but can't find any
| public information.
|
| Bit early to start using WebTransport seems to be the
| conclusion.
| travisd wrote:
| I skimmed the page, but couldn't quite tell: is this what the
| WHATWG Streams API is becoming? (ie streams with back-
| pressure?)
| matt_oriordan wrote:
| I know, we're very excited about WebTransport and what it can
| offer. As you say, on the surface it seems to provide both a
| more performant and reliable transport for realtime
| communications. Once it hits mainstream, we'll be certainly
| adding it as another transport we support in our stack
| (currently websockets, HTTP, SSE, MQTT etc)
|
| Matt, co-founder of Ably
| bullen wrote:
| If you want something simpler for real-time communication you can
| use comet-stream. It goes through all firewalls and scales better
| than most single threaded websocket servers:
| https://github.com/tinspin/rupy/wiki/Comet-Stream
| capableweb wrote:
| How does that work in the browser context? Just one long-living
| HTTP request that the server streams messages too? How does the
| browser reply? It's hard to understand how it's duplex and
| real-time over just HTTP without making more than one HTTP
| request.
| bullen wrote:
| You have two sockets, one eternal response with transfer-
| encoding: chunked, which is basically
| <hex_length>\r\n<data>\r\n\r\n over and over again, so very
| compact.
|
| On the browser to server it gets a bit heavier because you
| need GET /path?data=<message> HTTP/1.1\r\nHost:
| kinda.verbose.com\r\n\r\n and then each request gets a
| response that can be either zero so 200 OK\r\nContent-Length:
| 0\r\n\r\n or contain a sync. response. It looks bad but trust
| me that verbosity is a rounding error when it comes to the
| real bottleneck which is CPU concurrent atomic parallelism,
| and for that you basically need to use Java:
|
| https://github.com/tinspin/rupy/wiki (Most people disagree
| but the VM + GC and Javas memory model allows for atomic
| shared memory like none other, not even C/C++ can compete
| because you need a VM with GC to make that memory model work,
| they tried to copy it into C++11 and that was a faceplant of
| epic proportions that is still C++ memory model).
| latch wrote:
| Diving a little deeper down:
|
| 1 - A websocket "frame" has a variable-length header.
| Client->Server the header can be 6, 8 or 14 bytes. Server->Client
| it can be 2, 4 or 10. This is to support payloads < 125 bytes, <
| 2^16 and up to 2^64. I wish it was just a fixed 4-byte length.
|
| 2 - Frames can be fragmented to support streaming (where the
| sender or possibly a proxy doesn't know/want to buffer the entire
| response ahead of time). I feel like this is unnecessary in 99%
| of the cases. It wouldn't be so annoying..except control frames
| can be interspersed within fragmented frames. This is so that you
| can send a "ping" while streaming a large message over multiple
| fragments. Why didn't they just use one of those reserved bits
| for this?
|
| 3 - Client->Server payload is masked with 4 bytes (bitwise xor)
| so every message your server gets has to be unmasked.
___________________________________________________________________
(page generated 2022-01-11 23:00 UTC)