Live data from Hacker News

The hidden complexity of scaling WebSockets

composehq.com

51–60 of 72 posts

Re: The hidden complexity of scaling WebSockets

#51

Earlier quoted context omitted.

It solves the very limited problem of bike-shedding envelope shapes for request/reply protocols, which I think was all they meant to say. At its core, JSON-RPC boils down to "use `id` and `method` and work the rest out", which is acceptably minimal but does leave you with a lot of other issues to deal with.

It's a bit misnomer because it defines rpcs _and_ notifications. What people seem to be often missing for some reason is that those two map naturally to existing semantics of the programming language they're already using. What it means in practice is that you are exposing and consuming functions (ie. on classes) – just like you do in ordinary libraries. In js/ts context it usually means async functions on classes an…

That do you see as the difference between an RPC and a notification?

The terminology is not ideal, I grant, but a JSON-RPC "notification" (a request with no id) is just a request where the client cannot, and does not, expect any response, not even a confirmation that the request was received and understood by the server. It's like UDP versus TCP.

> emitting individual objects for array results

This is interesting! How does this change the protocol? I assume it's more than just returning multiple responses for the same request?

Re: The hidden complexity of scaling WebSockets

#52
post #49

I have been working on an idea/Node.js library called vramework.dev recently, and a big part of it focuses on addressing the main complexities mentioned below. For a bit of background, in order to tackle scalability, the initial approach was to explore serverless architecture. While there are both advantages and disadvantages to serverless, a notable issue with WebSockets on AWS* is that every time a message is recei…

  const onConnect: ChannelConnection = async (services, channel) => {
    // On connection (like onOpen)
    channel.send('hello') // This is checked against the input type
  }

  const onDisconnect: ChannelDisconnection = async (services, channel) => {
    // On close
    // This can't send anything since channel closed
  }

  const onMessage: ChannelMessage = async (services, channel) => {
    channel.send('hey')
  }

  export const subscribeToLikes: ChannelMessage = async (services, channel, { action, talkId }) => {
    const channelName = services.talks.getChannelName(talkId)
    // This is a service that implements a pubsub/eventhub interface
    await services.eventHub.subscribe(channelName, channel.channelId)
    // we return the action since the frontend can use it to route to specific listeners as well (this could be absorbed by vrameworks runtime in future)
    return { action, likes: await services.talks.getLikes(talkId) }
  }

  addChannel({
    name: 'talks',
    route: '/',
    auth: true,
    onConnect,
    onDisconnect,
    // Default message handler
    onMessage,
    // This will route the message to the correct function if a property action exists with the value subscribeToLikes (or otherwise)
    onMessageRoute: {
      action: {
        subscribeToLikes: {
          func: subscribeToLikes,
          permissions: {
            isTalkMember: [isTalkMember, isNotPresenter],
            isAdmin
          },
        },
      },
    },
  })

A code example.

Worth noting you can share functions across websockets as well, which allows you to compose logic across different ones if needed

Re: The hidden complexity of scaling WebSockets

#53
My SaaS has been using WebSockets for the last 9 years. I plan to stop using them and move to very simple HTTP-based polling.

I found that scalability isn't a problem (it rarely is these days). The real problem is crappy network equipment all over the world that will sometimes break websockets in strange and mysterious ways. I guess not all network equipment vendors test with long-lived HTTP websocket connections with plenty of data going over them.

At a certain scale, this results in support requests, and frustratingly, I can't do anything about the problems my customers encounter.

The other problems are smaller, but still annoying, for example it isn't easy to compress content transmitted through websockets.

Re: The hidden complexity of scaling WebSockets

#54
post #53

My SaaS has been using WebSockets for the last 9 years. I plan to stop using them and move to very simple HTTP-based polling. I found that scalability isn't a problem (it rarely is these days). The real problem is crappy network equipment all over the world that will sometimes break websockets in strange and mysterious ways. I guess not all network equipment vendors test with long-lived HTTP websocket connections wit…

Found this same issue trying to scale streamlit. It's just not a good idea.

Re: The hidden complexity of scaling WebSockets

#55

Elixir will get you pretty far along this scaling journey without too many problems: https://hexdocs.pm/phoenix/channels.html

> Elixir will get you pretty far along this scaling journey without too many problems:

been running a phoenix app in prod for 5 years. 1000+ paying customers. heavy use of websockets. never had an issue with the channels systems. it does what it says on the tin and works great right out of the box

Re: The hidden complexity of scaling WebSockets

#57
post #53

My SaaS has been using WebSockets for the last 9 years. I plan to stop using them and move to very simple HTTP-based polling. I found that scalability isn't a problem (it rarely is these days). The real problem is crappy network equipment all over the world that will sometimes break websockets in strange and mysterious ways. I guess not all network equipment vendors test with long-lived HTTP websocket connections wit…

The last project I worked on went in the same direction.

Everything works great in local/qa/test, and then once we move to production we inevitably have customers with super weird network security arrangements. Users in branch offices on WiFi hardware installed in 2007. That kind of thing.

When you are building software for other businesses to use, you need to keep it simple or the customer will make your life absolutely miserable.

Re: The hidden complexity of scaling WebSockets

#58
I am really unsure why devs around the world keep defaulting to websockets for things that are made for server sent events. In 90% of the usecases i see, websockets are just not the right fit. Everything is simpler and easier with SSE. Some exceptions are high throughput >BI<directional data streams. But even if eg. your synced multiplayer cursors in something like figma use websockets don't use it for everything else eg. your notification updates.

Re: The hidden complexity of scaling WebSockets

#59
post #56

Question for those in the know: Why would I use websockets over SSE?

Websockets are bidirectional while SSE is unidirectional (server to client). That said, there's nothing stopping you from facilitating client to server communication separately from SSE, you just don't have to build that channel with websockets.

Re: The hidden complexity of scaling WebSockets

#60
post #53

My SaaS has been using WebSockets for the last 9 years. I plan to stop using them and move to very simple HTTP-based polling. I found that scalability isn't a problem (it rarely is these days). The real problem is crappy network equipment all over the world that will sometimes break websockets in strange and mysterious ways. I guess not all network equipment vendors test with long-lived HTTP websocket connections wit…

I always recommend looking at Server-Sent Events [0] and EventSource [1]. It's a standardization of old style long-polling, mapping very well to the HTTP paradigm and is built in to the web standard.

It's so much easier to reason about than websockets, and a naive server side implementation is very simple.

A caveat is to only use them with HTTP 2 and/or client side logic to only have one connection open to the server, because of browser limits on simultaneous requests to the same origin.

[0] https://developer.mozilla.org/en-US/docs/Web/API/Server-sent... [1] https://developer.mozilla.org/en-US/docs/Web/API/EventSource

Post reply on HN