permessage-deflate support in ActionCable

Greetings!

I’m working on a custom use case of ActionCable.

It’s a bit complex to present here but let’s say that I have a bunch of clients connected to my rails backend only through an ActionCable websocket. These clients are physical devices that use only 3G/4G connections. In order to limit our operating costs, I’d like to save as much bandwidth as possible. To this end, I explored how was the support of gzipping messages in a WS connection.

I ended up reading about the permessage-deflate header (RFC 7692: Compression Extensions for WebSocket) which browser support seems to be good. I was wondering if I could enable it on ActionCable.

It turns out that ActionCable relies on the websocket-driver gem which has some support for websocket extensions. Fortunately, the permessage-deflate extension for websocket-driver is already implemented (see https://github.com/faye/permessage-deflate-ruby).

In term of rails code, the ActionCable::Connection::ClientSocket class is responsible for encapsulating the WebSocket::Driver. Once we have the WebSocket::Driver instance, we can simply call @driver.add_extension(PermessageDeflate).

I tried this locally by overriding the ActionCable::Connection::ClientSocket class definition (I know that’s bad) and it works properly: when ActionCable see a WS connection handshake with the header Sec-WebSocket-Extensions:

permessage-deflate, it replies with the correct header and the frames are compressed.

I hate having class definitions overrides in my code and I was wondering if it could be a good idea to let ActionCable handle this part or perhaps having an optional support for frames compression?

I know that it’s very specific for my use case but having smaller frames could benefit all the usages, even the default one: messages sent to a user browser.

Thoughts?

David

1 Like

I would love this - I’m working on a gem for collaborative editing with operational transforms, and think this would be a perfect fit. Have you made progress here?