Closed vinniefalco closed 2 years ago
Has this been implemented yet (as of boost 1.68)? If not, when is message compression used in a Beast WebSocket client?
There are three things which need happen for compression to be active on a stream:
Compile-time enablement. This is achieved through a bool deflateSupported
template parameter, which defaults to true. Setting it to false can make your compiled code smaller.
Run-time enablement. This is controlled by the function stream::set_option
. By default, clients are enabled and servers are disabled. However, this is only meaningful if deflateSupported==true
. Otherwise, if compile-time enablement is off then permessage-deflate (the canonical term for websocket compression) is of course never possible.
Negotiation enablement. When the WebSocket upgrade request/response cycle is performed, the client and server attempt to negotiate (or not) the permessage-deflate settings. The outcome of this negotiation depends on both the compile-time and the run-time enablement of both peers. The client can request compression, but the server has to OK it. Otherwise there is no compression. The permessage_deflate
option structure allows the client to configure the permissible results of the handshake.
This complexity is unfortunately a consequence with the permessage-deflate specification, which you might try reading: https://tools.ietf.org/html/rfc7692
Hope this helps!
It certainly does. If I got this correctly, by default, a Beast WS client stream has compression (per-message deflate) enabled, pending other conditions (server negotiation).
Thanks.
Sorry to resurrect this old issue, but it's still open. After the three conditions are met the server and client "can" exchange compressed messages. But it seems to be no way to specify, for a specific message if I want to compress it or not. It seems to me that beast suppose that if permessage_deflate is enabled I want to compress all the messages. In my case there are some messages that I need to leave uncompressed for speed reason, the time spent in deflate is not acceptable, but I want to compress all the other messages. I don't see in the write methods any way to specify if that specific message need to be compressed or not.
@pscamodio
From the height of my ignorance, doesn't this work?
// Disable compression
websocket::permessage_deflate pmd;
ws.get_options(pmd);
pmd.client_enable = false;
pmd.server_enable = false;
ws.set_options(pmd);
// Use the was stream
ws.read(/* ... */); // or whatever operation
// Enable compression
ws.get_options(pmd);
pmd.client_enable = true;
pmd.server_enable = true;
ws.set_options(pmd);
If this does work, then it might not be a huge problem, although this is probably verbose enough to justify some wrapper function.
I like your thinking here, but the meaning of "enable" is just that it is allowed as a negotiation option during handshake. Whether or not compression is actually enabled is a property of the stream. See: https://github.com/boostorg/beast/blob/00293a6adb5383fe14217a8916dd7ff79a857483/include/boost/beast/websocket/impl/stream_impl.hpp#L100
The code to implement this might already be there, you would just need to add a member function and tests.
Yes. I was looking at
right now, and trying to find a solution to this issue and https://github.com/boostorg/beast/issues/227.
So this issue is just a matter of agreeing on the API to enable/disable wr_compress_opt
, while #227 is just a matter of including an extra min size condition at the line above.
The minimum size should be configurable, with a reasonable default (see what other libs do, like uWebsockets)
When permessage-deflate is negotiated on a stream, It should be possible to control whether compression is enabled on a per-message basis.