[undertow-dev] websocket per-message compression & design q
peter royal
peter.royal at pobox.com
Mon Aug 10 14:31:52 EDT 2015
Hi!
I'm trying to debug the problems I've encountered after enabling
per-message compression on websockets in 1.2,
https://issues.jboss.org/browse/UNDERTOW-508
One thing I've noticed is that there's an entirely different code path
used inside of WebSocket07FrameSinkChannel whenever extensions are
enabled. I was trying to think of how to refactor how extensions are
applied so that it would be a path that is always-on, and thus hopefully
subject to more scrutiny and use.
Conceptually, extensions are transformations to the ByteBuffer that
makes up a message payload. I think the internals might be a bit clearer
if they were treated as that, and then always applied. (the
ExtensionByteBuffer class is something I'd want to eliminate).
From an internal API point of view, calls to write on a websocket are
mostly made via the WebSockets class, and then a couple of places that
use the StreamSinkFrameChannel (SSFC) over a longer period of time for
partial messages and streams in the WS JSR implementation.
For sending, the GatheringByteChannel APIs are used to represent writing
a message. A collection of writes to a single SSFC will result in 1..n
WS message fragments depending on how large the buffers returned from
the allocator are. When using extensions, there are a bunch of
ergonomics regarding the return value from write and remaining bytes in
the provided buffers to enable
For the WebSockets send methods, all the data to send is already in
memory, and the methods just spin or wait over the SSFC writing
fragments until all the data is sent. Then there are the blocking APIs
in the JSR that send a single fragment and wait for it to be flushed.
I think it might be cleaner to push some of that responsibility from the
WebSockets utility class into the WebSocket07FrameSinkChannel. For the
non-blocking cases, that'd be merging the following two lines from
WebSockets into a single call,
StreamSinkFrameChannel channel = wsChannel.send(type, totalData);
WebSockets.sendData(data, wsChannel, callback, channel, null,
timeoutmillis);
The channel can then apply the extensions to data and do the appropriate
thing. Similar changes would happen to the blocking methods.
I realize this is a bit ramble-y, but I wanted to at least get some of
my thoughts out there. I'm eager to get WS extensions working fully, and
thought that re-architecting how the sending of WS messages happen might
make the code less brittle and easier to maintain
-pete
--
(peter.royal|osi)@pobox.com - http://fotap.org/~osi
More information about the undertow-dev
mailing list