Hi all,
according to the latest spec and API version (which is in GlassFish 80) (javadoc on @OnMessage):
Each websocket endpoint may only have one message handling method for each of the native websocket message formats: text, binary and pong.
Types produced from decoders are considered as text type as well, so you may have just one method with type produced by decoder.
Please see more in the api javadoc of javax.websocket.OnMessage, the policy is described in detail here.
Thanks,
Stepan
On Mar 14, 2013, at 2:50 PM, Andy Moncsek <amo.ahcp_at_gmail.com> wrote:
> Hi,
> The Exception (Caused by: javax.websocket.DeploymentException: Text MessageHandler already registered.) appears here
>
> MessageHandlerManager line 166
> else if (checkBinaryDecoders(handlerClass)) {//decodable binary
> if (binaryHandlerPresent) {
> throwException("Text MessageHandler already registered.");
> } else {
> binaryHandlerPresent = true;
> binaryWholeHandlerPresent = true;
> decoderExists = true;
> }
> }
>
> I have two binary messages and two decoders (each message one decoder...), so when the first method signature validated, the binaryHandlerPresent is true and no other can be registered. Do I miss something? I am wondering why Mohamed's example is working.
>
> Cheers
>
> Andy
>
>
> 2013/3/14 Mohamed Taman <mohamed.taman_at_gmail.com>
> Hi Andy,
>
> It is allowed to have more than @OnMessage per Endpoint. as in my code demo in JDC and it works with the same Glassfish b80 and Tyrus_b13.
>
> here is the code of endpoint, the 2 messages are in red.
>
> package com.taman.rtrc.endpoint.server;
>
> import com.taman.rtrc.endpoint.data.LoginMessage;
> import com.taman.rtrc.endpoint.data.LoginMessageDecoder;
> import com.taman.rtrc.endpoint.data.RunnerMessage;
> import com.taman.rtrc.endpoint.data.RunnerMessageConverter;
> import java.io.IOException;
> import java.util.concurrent.ConcurrentHashMap;
> import java.util.logging.Level;
> import java.util.logging.Logger;
> import javax.websocket.DeploymentException;
> import javax.websocket.OnClose;
> import javax.websocket.OnMessage;
> import javax.websocket.OnOpen;
> import static javax.websocket.RemoteEndpoint.Basic;
> import javax.websocket.Session;
> import javax.websocket.server.ServerEndpoint;
> import javax.websocket.server.ServerEndpointConfigurator;
> import org.glassfish.tyrus.server.Server;
>
> /**
> *
> * @author mohamed_taman
> */
> @ServerEndpoint(value = "/server/register",
> decoders = {RunnerMessageConverter.class, LoginMessageDecoder.class},
> encoders = {RunnerMessageConverter.class},
> configurator = ServerEndpointConfigurator.class)
> public class RTRCServer {
>
> final static Logger logger = Logger.getLogger(RTRCServer.class.getName());
> private static ConcurrentHashMap<String, Session> runners = new ConcurrentHashMap<>();
>
> @OnOpen
> public void init(Session runner) {
> try {
> logger.info(runner.getId());
> runner.getBasicRemote().sendText("Connected to RTRC server.");
> } catch (IOException ex) {
> logger.log(Level.SEVERE, null, ex);
> }
> }
>
> @OnMessage
> public void handleMessage(RunnerMessage msg) {
> logger.info(msg.toString());
>
> broadcast(msg);
> }
>
> @OnMessage
> public boolean doLogin(LoginMessage msg, Session runner) {
>
> logger.info(msg.toString());
>
> runners.put(msg.getUsername(), runner);
>
> logger.log(Level.INFO, "Current runneres = {0}", runners.size());
>
> return true;
> }
>
> @OnClose
> public void disconnected(Session runner) {
> String username = null;
> logger.info("The web socket closed");
> for (String s : runners.keySet()) {
> if (runners.equals(runners.get(s))) {
> username = s;
> runners.remove(s);
> break;
> }
> }
>
> logger.log(Level.INFO, "Current runneres = {0}", runners.size());
>
> if (username != null) {
> // this.addToTranscriptAndNotify(username, " has just left...rather abruptly !");
> }
> }
>
> private void broadcast(RunnerMessage msg) {
> logger.info("Broadcasting updated user list");
>
> for (Session nextSession : runners.values()) {
> Basic remote = nextSession.getBasicRemote();
> try {
> remote.sendText(msg.toJSON());
> } catch (IOException ioe) {
> logger.log(Level.WARNING, "Error updating a client {0} : {1}", new Object[]{remote, ioe.getMessage()});
> }
> }
> }
> }
>
> Also the selection is based on argument type sent.
>
>
>
>
>
> On Thu, Mar 14, 2013 at 1:26 PM, Andy Moncsek <amo.ahcp_at_gmail.com> wrote:
> Hi,
> I upgraded to glassfish b80 (tyrus 1.0-b13) today and realized that only one @OnMessage works per Endpoint?! Can you confirm this? I get a validation error from GF, so this seem to be a wanted behavior. Also in tyrus SVN I can find comments like this: "MessageHandler registration validity checking algorithm (also applicable for annotated case).". So what was the reason to do so? Do I really have to deal with generic messages to communicate with one endpoint?
>
> Thanks
>
> Andy
>
>
>
> --
>
> Thanks & Best Regards
>
>
> “Improve your Life through Science and Art…”
>
> Mohamed Mahmoud Taman
>
> Business Solutions,
>
> Systems Architect & Design Supervisor
>
> Java Team Leader
>
> | JCP (Java Community Process) Member
>
> |Oracle Egypt Architects Club board member
>
> | JavaOne & EG-JDC Speaker
>
> | SCJP, SCWCD, OCP PL/SQL
>
>
> e-finance,BLDG17, Smart Village,
>
> KM 28 Cairo-Alex Desert Road,
>
> Ground Floor, Giza, Egypt
> Postal Code : 12577
>
> ( : +(202) 3827 1422
>
> (: +(202) 3827 1499
>
> (: +(202) 3827 1599
>
> È: +(201) 00531 8017
>
> P Before you print Think about Your ENVIRONMENTAL responsibility.
>
>