在 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的主要内容,如果未能解决你的问题,请参考以下文章
HTML5 postMessage 和 onmessage API 具体应用
Vue.js 在 websocket onmessage 事件中更新 html