Java 在 onMessage 注释中有多个数据的 Websockets

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22061297/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 13:19:13  来源:igfitidea点击:

Websockets with multiple datas in onMessage annotation

javawebsocket

提问by user2350138

I am using websockets. I want to use multiple @onMessage overloaded methods with different data types. In Client side i a have the following methods

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

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

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

Where Message is pojo class and decoded and encoded it.

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

In server side

在服务器端

   @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);
    }
}

I am getting the following error

我收到以下错误

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.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)

can any one suggest us how to use multiple types of data sending to/from the server.

任何人都可以建议我们如何使用向/从服务器发送的多种类型的数据。

采纳答案by Pavel Bucek

This is not possible. JSR 356defines clearly that there can be only one message handler per text message, one per binary message and one per PongMessage. See @OnMessagejavadoc:

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

======

======

This method level annotation can be used to make a Java method receive incoming web socket messages. Each websocket endpoint may only have one message handling method for each of the native websocket message formats: text, binary and pong. Methods using this annotation are allowed to have parameters of types described below, otherwise the container will generate an error at deployment time.

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

The allowed parameters are:

允许的参数是:

  1. Exactly one of any of the following choices
  2. and Zero to n String or Java primitive parameters annotated with the javax.websocket.server.PathParamannotation for server endpoints.
  3. and an optional Sessionparameter
  1. 正好是以下任一选项之一
  2. 零到 n 字符串或 Java 原始参数,使用服务器端点的javax.websocket.server.PathParam注释进行注释。
  3. 和一个可选的Session参数
参数可以按任何顺序列出。

The method may have a non-void return type, in which case the web socket runtime must interpret this as a web socket message to return to the peer. The allowed data types for this return type, other than void, are String, ByteBuffer, byte[], any Java primitive or class equivalent, and anything for which there is an encoder. If the method uses a Java primitive as a return value, the implementation must construct the text message to send using the standard Java string representation of the Java primitive unless there developer provided encoder for the type configured for this endpoint, in which case that encoder must be used. If the method uses a class equivalent of a Java primitive as a return value, the implementation must construct the text message from the Java primitive equivalent as described above.

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

Developers should note that if developer closes the session during the invocation of a method with a return type, e method will complete but the return value will not be delivered to the remote endpoint. The send failure will be passed back into the endpoint's error handling method.

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

For example:

例如:


 @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.Readerjava.io.Reader, java.nio.ByteBufferjava.nio.ByteBufferjava.io.InputStream注释方法完成后的java.io.InputStream,因为它们可能会被实现回收。