users@websocket-spec.java.net

[jsr356-users] [jsr356-experts] Re: Re: Call precedence of multiple MessageHandlers

From: Danny Coward <danny.coward_at_oracle.com>
Date: Tue, 06 Nov 2012 15:41:44 -0800

On 11/2/12 5:36 PM, Scott Ferguson wrote:
> On 11/2/12 4:59 PM, Danny Coward wrote:
>> Hi folks,
>>
>> Another question that has come up as people look at the API and
>> implement it is the issue of precedence when an endpoint has multiple
>> MessageHandlers. I wrote up a little proposal that seeks to define
>> how the container is supposed to select which of potentially numerous
>> of MessageHandlers to callwhen a web socket message arrives.
>
> I've been working through this in our implementation. (Decoders is a
> different/related/bigger issue.)
>
> More comments inline, but the summary is I think it's best to only
> allow one Text handler and one Binary handler, and throw an
> IllegalStateException at registration time if more than one of each
> type is registered.
Yeah I think I agree with everyone: what I wrote up is too complicated.

But let me make sure I understand, are you thinking that you'd only
allow one of any of the several different text-message handlers:
{MessageHandler.Text, MessageHandler.AsyncText,
MessageHandler.DecodedObject<T> with Decoder.Text<T> or
Decoder.TextStream<T>} to be registered per connection, and one of the
several different binary-message handlers {analogous list} to be
registered ? So you can have at most two handlers per connection, and
the developer has to pick his mode of consumption for both text and binary?

- Danny
>
>>
>> Principles
>>
>> Each web socket message is handled by at most one message handler
>
> Yes.
>
>> Messages that are unhandled result in calls to
>> onError/_at_WebSocketError callbacks, so developers can always know if a
>> message does not get handled
>
> Yes.
>
>> Developer provided decoders are chosen before platform decoders.
>
> Our decoder logic is messed up for bigger reasons, but I want to put
> that discussion off to a different thread.
>
>> If a decoder fails, the error is delivered and no more decoders are
>> attempted.
>
> Ditto. (decoders messed up).
>> MessageHandlers for custom objects (provided a Decoder exists) are
>> chosen over the basic MessageHandlers
>
> Ditto. (decoders messed up).
>>
>> Process
>
> Comment at end.
>>
>> 1. a whole string message arrives
>>
>> a) if there is an MessageHandler.AsyncText handler - call it once
>> with the whole string and stop, otherwise continue...
>> b) if there is an MessageHandler.CharStream handler - call it once
>> using the whole string as the source and stop, otherwise continue...
>> c) if there is a MessageHandler.DecodedObject<T> where T is not
>> String, then try to find a Decoder.Text<T> or a
>> Decoder.TextStream<T>. Look, in order, through developer provided
>> ones (single list, may contain both Text and TextStream types). Then
>> look through platform provided ones. Use the first match to decode
>> it. If the decode completes without error, call the MessageHandler
>> and stop, if not, call the onError/_at_WebSocket method with the decode
>> exception and stop. If there is no suitable Decoder, continue....
>> d) if there is a MessageHandler.Text handler handler, call it, using
>> the first developer provided Decoder.TextStream<String> or
>> Decoder.Text<String>, if any.
>> e) If the message is still unhandled, call back on the
>> onError/_at_WebSocketError method. We may need a new exception type for
>> Unhandledmessages.
>>
>> 2) a whole binary message arrives: use analogous process to 1)
>>
>> 3) the first piece of a chunked string message arrives.
>>
>> a) if there is an MessageHandler.AsyncText handler - call it
>> repeatedly until all the message has arrived and stop, otherwise
>> continue..
>> b) if there is an MessageHandler.CharStream handler - call it with a
>> Reader linked to the incoming parts, and stop, otherwise continue..
>> c) if there are MessageHandler.Text or MessageHandler.DecodedObject
>> handlers, wait for all the string pieces to arrive, building the
>> whole message as you go (subject to the buffer limit defined on the
>> *Container). If the buffer limit is exceeded call the
>> onError/_at_WebSocketError method on the endpoint. Otherwise, using the
>> whole message, jump to the analogous steps for 1c), d) and e) to
>> process the complete message.
>>
>> 4) the first piece of a chunked binary message arrives: use analogous
>> process to 3)
>
> Imagine the replacement specification:
>
> 1) If a text message comes in (chunked or not), the single text
> MessageHandler is used.
>
> 2) If a binary message comes in (chunked or not), the single binary
> MessageHandler is used.
>
> Done.
>
> I don't think there's any practical power lost by this restriction,
> and the limitation is far outweighed by the benefit of a simpler
> definition.
>
> -- Scott
>
>> --
>> <http://www.oracle.com> *Danny Coward *
>> Java EE
>> Oracle Corporation
>>
>


-- 
<http://www.oracle.com> 	*Danny Coward *
Java EE
Oracle Corporation