在 onMessage 注释中具有多个数据的 Websocket

Posted

技术标签:

【中文标题】在 onMessage 注释中具有多个数据的 Websocket【英文标题】:Websockets with multiple datas in onMessage annotation 【发布时间】:2014-02-27 07:02:09 【问题描述】:

我正在使用 websocket。我想使用具有不同数据类型的多个 @onMessage 重载方法。 在客户端我有以下方法

   @OnMessage
public void onMessage(Message message) 
    System.out.println(message.getContent()+":"+message.getSubject());


@OnMessage
public void onMessage(String message) 
    System.out.println(message);

Message 是 pojo 类并对其进行解码和编码。

在服务器端

   @OnMessage
public void onMessage(String msg, Session session) 
    try 

        System.out.println("Receive Message:" + msg);

        session.getBasicRemote().sendText("\"subject\":\"This is subject1\",\"content\":\"This is content1\"");
        session.getBasicRemote().sendText("This is Example Test");


     catch (IOException ex) 
        Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
    

我收到以下错误

javax.websocket.DeploymentException: Class: clientwebsocket.MyClient. Text MessageHandler already registered.

at org.glassfish.tyrus.core.ErrorCollector.composeComprehensiveException(ErrorCollector.java:83)
at org.glassfish.tyrus.client.ClientManager$1.run(ClientManager.java:384)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at org.glassfish.tyrus.client.ClientManager$SameThreadExecutorService.execute(ClientManager.java:565)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:110)
at org.glassfish.tyrus.client.ClientManager.connectToServer(ClientManager.java:343)
at org.glassfish.tyrus.client.ClientManager.connectToServer(ClientManager.java:182)
at clientwebsocket.ClientWebSocket.start(ClientWebSocket.java:31)
at clientwebsocket.ClientWebSocket.main(ClientWebSocket.java:40)

谁能建议我们如何使用多种类型的数据发送到服务器/从服务器发送。

【问题讨论】:

【参考方案1】:

这是不可能的。 JSR 356 明确定义每个文本消息只能有一个消息处理程序,每个二进制消息一个,每个PongMessage 一个。见@OnMessagejavadoc:

======

此方法级别的注释可用于使 Java 方法接收传入的 Web 套接字消息。每个 websocket 对于每种原生 websocket 消息格式,端点可能只有一种消息处理方法:文本、二进制和 pong。方法 允许使用此注解 下面描述的类型的参数,否则容器会在部署时产生错误。

允许的参数是:

    以下选项之一 如果该方法正在处理文本消息: java.lang.String 接收整个消息 用于接收转换为该类型的整个消息的 Java 原语或等效类 String 和布尔对分段接收消息 java.io.Reader 将整个消息作为阻塞流接收 端点具有文本解码器的任何对象参数(Decoder.Text 或 Decoder.TextStream)。 如果方法正在处理二进制消息: byte[] 或java.nio.ByteBuffer 接收整个消息 byte[] 和布尔值对,或java.nio.ByteBuffer 和布尔值对来分批接收消息 java.io.InputStream 将整个消息作为阻塞流接收 端点具有二进制解码器的任何对象参数(Decoder.Binary 或 Decoder.BinaryStream)。 如果方法正在处理 pong 消息: PongMessage 用于处理 pong 消息 和零到 n 字符串或 Java 原始参数 使用javax.websocket.server.PathParam 注释为服务器端点进行注释。 和一个可选的Session 参数
参数可以按任何顺序列出。

该方法可能具有非 void 返回类型,在这种情况下,Web 套接字 运行时必须将此解释为 Web 套接字消息以返回给对等方。 此返回类型允许的数据类型(除 void 外)为 String、 ByteBuffer、byte[]、任何 Java 原语或等效类,以及任何用于 其中有一个编码器。如果该方法使用 Java 原语作为返回 值,实现必须使用 Java 原语的标准 Java 字符串表示,除非有开发人员 提供了为此端点配置的类型的编码器,其中 必须使用编码器的情况。如果该方法使用 一个类等价于作为返回值的 Java 原语,实现 必须从等效的 Java 原语构造文本消息 如上所述。

开发者应该 请注意,如果开发人员在调用具有返回类型的方法期间关闭会话,则 e 方法将完成,但 返回值不会传递到远程端点。发送失败将被传递回端点的错误处理方法。

例如:


 @OnMessage
 public void processGreeting(String message, Session session) 
     System.out.println("Greeting received:" + message);
 
 
例如:

 @OnMessage
 public void processUpload(byte[] b, boolean last, Session session) 
     // process partial data here, which check on last to see if these is more on the way
 
 
开发人员不应继续引用java.io.Reader、java.nio.ByteBuffer 类型的消息对象 或 java.io.InputStream 在注释方法完成后,因为它们 可以被执行回收。

【讨论】:

知道为什么在以下情况下我会遇到类似的异常。我有端点类,它定义了一个文本 onMessage 处理程序。我从它继承了一个新类,将其注释为服务器端点并指定了不同的文本 onMessage 处理程序。为什么父类 onMessage 处理程序被认为是冲突的?

以上是关于在 onMessage 注释中具有多个数据的 Websocket的主要内容,如果未能解决你的问题,请参考以下文章

onMessage 在 iOS 上运行多个异步任务

具有两个或多个返回参数的函数注释

HTML5 postMessage 和 onmessage API 具体应用

Vue.js 在 websocket onmessage 事件中更新 html

onMessage 数据:“RemoteMessage”实例(想在控制台上打印消息)

window.onmessage 在反应 js 组件中不起作用