[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)