users@websocket-spec.java.net

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

From: Danny Coward <danny.coward_at_oracle.com>
Date: Wed, 07 Nov 2012 17:58:17 -0800

Hi Scott, all,

>>> 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?
>
> Yes. That's what I was thinking.
OK I see. I definitely like the simplicity much better than my original
writeup, but it does a little restrictive to limit the developer to
one/two handlers.

There's a different approach to consider that might be even simpler...

- Allow multiple MessageHandlers to be registered in an (ordered) list.
When a message comes in, just pick the first MessageHandler in the list
that is able to handle the message, and stop.

...yet retain the flexibility to handle different types of messages with
different handlers, for those that want to.

So, for example, if you have a MessageHandler.Text at the front of the
handler list, its going to consume all the text messages.
And for example, If your handler list is like this:
[MessageHandler.DecodedObject<Apple>, MessageHandler.Text] where there's
Decoder<Apple> configured, then the MessageHandler.DecodedObject<Apple>
will handle all the text messages that the Decoder can turn into an
Apple, and the MessageHandler.Text will handle all the text messages
that cannot be turned into an Apple.
etc.

That way, you can have a mix of handlers, with a simple (simpler?) rule
for consumption whatever the handler type.

One reason I think to keep the flexibility of multiple handlers, is that
I think being able to write this kind of POJO is going to be a useful one:-

@WebSocketEndpoint(
     "/chat",
     {ChatMessageDecoder.class, LogoutMessageDecoder.class});
public void ChatServer {

     @WebSocketMessage
     public void chat(ChatMessage cm) {
     }

     @WebSocketMessage
     public void logout(LogoutMessage lm) {
     }

     @WebSocketMessage
     public void statusMessage(String statusMessage) {
     }

}

where ChatMessageDecoder implements Decoder.Text<ChatMessage> and
LogoutMessageDecoder implements Decoder.Text<LogoutMessage>.

Separately, Scott I logged your suggestion earlier in the thread to move
the registration of decoders 'closer' to the MessageHandlers - I agree
doing so will make the case of having a MessageHandler.DecodedObject<T>
without a Decoder for objects of type T less common.

- Danny









>
> In practice, I'd expect most sub-protocols would be either text or
> binary but not both. (Not enforced, of course.)



>
> -- Scott
>


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