[undertow-dev] Websocket High Level API

Norman Maurer nmaurer at redhat.com
Wed Jan 30 09:32:39 EST 2013


Hi guys,

so I think the High Level API is now in very good shape for another review. All the tests of the Autobahn Testsuite[1] now pass with the High Level API and the Low Level API, so it seems like it is full working (yay!).
I had to make a few changes to the API to correctly support fragmented Frames. There are still a few things to work on but I think the current code shows how the API will look like. The API was build with WebSocket JSR in
mind which will be build on top of it.

Find it as always here [2]. 

Feel free to send feedback.

Bye,
Norman


[1] http://autobahn.ws/testsuite
[2] https://github.com/normanmaurer/undertow/tree/websockets_high_level_api

---
Norman Maurer
nmaurer at redhat.com

JBoss, by Red Hat



Am 29.01.2013 um 07:00 schrieb Norman Maurer <nmaurer at redhat.com>:

> 
> Am 29.01.2013 um 00:43 schrieb Stuart Douglas <sdouglas at redhat.com>:
> 
>> 
>> 
>> Norman Maurer wrote:
>>> 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.
>> 
>> Using an abstract frame handler to do the assembly sounds like a better idea.
> 
> Please see my last email… I did go with an interface because so we can make it more performant by just do the assembly in our core.
> 
>> 
>>> 
>>> 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
>> 
>> This is probably ok, there is however some info that I think we need to provide:
>> 
>> - So way of taking the idle time on the connection, so if the client has sent a ping the application has some way of knowing that the client is still alive.
>> 
>> - When the close frame is received the application should receive some kind of notification with any data that was in the close frame.
> 
> I guess you are right.. Let me change this.
> 
>> 
>> - Pong frames should definitely not be ignored, if the application has decided to send a ping frame they would want to be notified of the result.
> 
> Again please see my last email.. The user is notified when a Pong is received. Just the content is ignored which is fine as the Pong will just contain the same as the ping.
> 
> 
>> 
>>> 
>>> 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);
>> 
>> Sounds reasonable.
>> 
>>> 
>>> * WebSocketFrame
>>> Should be renamed to WebSocketFrameHeader or something like this if we
>>> keep it like it is atm.
>> 
>> +1
>> 
>> Stuart
>> 
>>> 
>>> 
>>> 
>>> ---
>>> Norman Maurer
>>> nmaurer at redhat.com <mailto:nmaurer at redhat.com>
>>> 
>>> JBoss, by Red Hat
>>> 
>>> 
>>> 
>>> Am 25.01.2013 um 02:25 schrieb Stuart Douglas <sdouglas at redhat.com
>>> <mailto:sdouglas at 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_api#diff-5
>>>> 
>>>> 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_api#L9R98
>>>> 
>>>> 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
>>>> 
>>> 
> 
> 
> ---
> Norman Maurer
> nmaurer at redhat.com
> 
> JBoss, by Red Hat
> 
> 
> 
> _______________________________________________
> undertow-dev mailing list
> undertow-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/undertow-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20130130/dc9fb05c/attachment.html 


More information about the undertow-dev mailing list