And it is again me ;)
I spend more time today to experiment with the API and do some more refactoring of it.
The biggest change is:
Rework the FrameHandler API and so split FrameHandler into 3 interfaces:
- FrameHandler itself is notified for PING,PONG and CLOSE frames but without
the payload as I don't see a real use case here in the high-level API
- AssembledFrameHandler which extends FrameHandler and has two methods to act
on assembled TEXT and BINARY frames. Binary payload can be passed in as an
array of ByteBuffer to allow the implementation to use more then one buffer
when for example buffer pooling is used and it not fit in one buffer.
- PartialFrameHandler which extends FrameHandler and has two method to act
on partial TEXT and BINARY frames
- Automatically handle PING (respond with PONG)
- Automatically handle CLOSE (respond with CLOSE) and close channel
- Automatically handle PONG (discard)
I would love to get some feedback on this. You can find the code here:
I'm not 100 % sure yet if I like the PartialFrameHandler but I had no better idea for
it yet…
You can see it in action here:
Bye,
Norman
---
Norman Maurer
nmaurer(a)redhat.com
JBoss, by Red Hat
Am 25.01.2013 um 15:56 schrieb Norman Maurer <nmaurer(a)redhat.com>:
Hi guys,
I just did a few changes based on Stuarts branch which address some of my comments
* Rename WebSocketFrame to WebsocketFrameHeader
* Fix implementations to make use of the proposed API
* Add method to send a binary frame using a FileChannel as source for the payload to make
use of zero-copy if possible. I did not implement this for Text frames as these MUST only
contain UTF8 and I think it would be quite to easy to send invalid data as a Text Frame
when use a FileChannel.
So the rest of my comments is still valid ;)
You can find my current work here:
https://github.com/normanmaurer/undertow/tree/websockets_high_level_api
---
Norman Maurer
nmaurer(a)redhat.com
JBoss, by Red Hat
Am 25.01.2013 um 11:05 schrieb Norman Maurer <nmaurer(a)redhat.com>:
> Hey Stuart,
>
> thanks for start the thread. I just finished the review of your changes and have a
few comments.
>
> * FrameHandler:
> I don't know if I like the fact that the same interface is used for
"assembled Fragments" (when
WebSocketSession.setAutomaticallyAssembleFragments(true) was used) and not assembled
Fragments (when WebSocketSession.setAutomaticallyAssembleFragments(false) was used".
I think we really should either use another interface or do the assemble work in an
abstract implementation of the FrameHandler and just provide
> abstract methods to implement that act on the "assembled Frame" then. Also
with the current interface design it is up to the user to detect when the Frame is
complete by check if he received all of the data. I think we should make it easier and
just tell the user when it is complete.
>
> Also I wonder if it is really useful to also get notified with the frame content for
other frames then Binary and Text. My idea would be that we:
> - automatically respond to a Ping with a Pong
> - automatically echo back the Close Frame and after that close the connection
> - Ignore Pong frames
>
> The fact why I think we should just do this is that otherwise it is easy for the user
to make the whole thing messed up and so not be conform with the RFC anymore. Do you think
there are real use-cases for get the content of those in the high-level API ? If not we
may not want to expose this at all.
>
> * TextFrameSender / BinaryFrameSender
> What about add an extra method to it which takes a FileChannel, offset, length and
SendCallback as parameter. So we could make use of zero copy if a user want to send a file
content in a frame.
> Something like this:
>
> void sendBinary(FileChannel, long offset, long length, SendCallback callback);
>
> * WebSocketFrame
> Should be renamed to WebSocketFrameHeader or something like this if we keep it like
it is atm.
>
>
>
> ---
> Norman Maurer
> nmaurer(a)redhat.com
>
> JBoss, by Red Hat
>
>
>
> Am 25.01.2013 um 02:25 schrieb Stuart Douglas <sdouglas(a)redhat.com>:
>
>> Hi guys,
>>
>> Last night Norman and I had a bit of a talk about what the high level Websocket
API should look like, and Norman came up with some interfaces as a prototype.
>>
>> So after looking at Norman's prototype I had a bit more of a think about what
our high level API should look like and this is what I have come up with:
>>
>>
https://github.com/stuartwdouglas/undertow/compare/websockets_high_level_api
>>
>> I have been thinking about the use cases that we want to address with the high
level API, and when you would want to use the high level API vs the low level XNIO API.
>>
>> My thinking is that in general if you want to use async IO and deal with message
bytes as soon as they arrive this is covered quite nicely by our existing low level API.
The high level API should focus on async operations involving complete messages, and
blocking operations.
>>
>> The JSR 356 implementation will just be implemented as a fairly thin wrapper
around our high level API.
>>
>> Sending:
>>
>> This is handled by (Text|Binary)FrameSender.
>>
>> I think there are a few different use cases for the high level API in terms of
sending messages:
>>
>> - Complete message async, with a callback on completion
>> - Complete message blocking
>> - Complete message blocking with Stream / Writer
>> - Fragmented versions of all of the above.
>>
>> There is one use case that is not covered here, and that is sending a partial
messaged using async IO, as mentioned above the reason why I don't think we should
have this as part of the high level API is because this is essentially what is provided by
our low level API.
>>
>> Receiving:
>>
>> In terms of receiving I think that we should just have a single handler type:
>>
>>
https://github.com/stuartwdouglas/undertow/compare/websockets_high_level_...
>>
>> This just receives complete messages. I think this is preferable to having to
register 5 different types of handler for every frame type.
>>
>> These handlers just receive complete messages that are fully buffered.
>>
>> In terms of fragmented messages I think we should provide 2 ways of dealing with
them, and have a setting that controls which one is in use:
>>
>>
https://github.com/stuartwdouglas/undertow/compare/websockets_high_level_...
>>
>> If this is true then we will just assemble the fragmented messaged automatically
and deliver it as 1 logical message. Otherwise they will just be delivered as they
arrive.
>>
>> I would have liked to provide a way to receive messages via an InputStream /
Reader, to provide a way to get around fully buffering messaged when using blocking IO,
however I can't really think of a nice way to do this.
>>
>> What do you guys think? I know there is still some stuff missing (e.g. we need a
way to propagate auth and session information from the original HTTP request).
>>
>> Stuart
>>
>
> _______________________________________________
> undertow-dev mailing list
> undertow-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/undertow-dev
_______________________________________________
undertow-dev mailing list
undertow-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/undertow-dev