What are the encoder or decoder list listings in WebSocket EndPoints annotation?

I am learning tyrus WebSocket implementation. But I don’t understand why and when we need more than one encoder or decoders at websocket endpoints. For instance:

@ServerEndpoint(value = "/subscribe", decoders = { TextStreamMessageDecoder.class }, encoders = { TextStreamMessageEncoder.class }) public class ChatServerEndPoint { ...... } 

The list of decoders and encoders has only one decoder and encoder. Since this is an array of decoders or encoders, I can use several types of encoders or decoders at a time. But in the above api description,

In the websocket production environment, the first decoder in the list will be used, able to decode the message, ignoring the remaining decoders.

If it always uses the first elements of the list, which ones are used in the encoder or decoder in the WebSockets API?

After editing

 public class TextStreamMessageDecoder implements Decoder.TextStream<JsonWrapper>{ public JsonWrapper decode(Reader reader) throws DecodeException, IOException { JsonReader jsonReader = Json.createReader(reader); JsonObject jsonObject = jsonReader.readObject(); return new JsonWrapper(jsonObject); } } public class TextStreamMessageEncoder implements Encoder.TextStream<JsonWrapper>{ public void encode(JsonWrapper object, Writer writer) throws EncodeException, IOException { JsonWriter jsonWriter = Json.createWriter(writer); JsonObject jsonObject = object.getJson(); jsonWriter.write(jsonObject); } } public class MessageDecoder implements Decoder.Text<JsonWrapper> { public JsonWrapper decode(String s) throws DecodeException { JsonObject json = Json.createReader(new StringReader(s)).readObject(); return new JsonWrapper(json); } public boolean willDecode(String s) { // TODO Auto-generated method stub try { Json.createReader(new StringReader(s)).read(); return true; } catch (JsonException ex) { ex.printStackTrace(); return false; } } } public class MessageEncoder implements Encoder.Text<JsonWrapper> { public String encode(JsonWrapper jsonWrapper) throws EncodeException { return jsonWrapper.getJson().toString(); } } @ClientEndpoint(decoders = { MessageDecoder.class}, encoders = { MessageEncoder.class }) public class ChatClientEndPoint { @OnMessage public void onMessage(String message, Session session) { logger.info("onMessage: " + session.getId()); if (this.messageHandler != null) this.messageHandler.handleMessage(message); } } @ServerEndpoint(value = "/subscribe", decoders = { TextStreamMessageDecoder.class, MessageDecoder.class}, encoders = { TextStreamMessageEncoder.class, MessageEncoder.class }) public class ChatServerEndPoint { @OnMessage public void onMessage(String message, Session session) { logger.info("onMessage: " + session.getId()); // logger.info("onMessage: " + message.toString()); Gson gson = new Gson(); ClientMessage clientMessage = gson.fromJson(message, ClientMessage.class); System.out.println(clientMessage.toString()); } } 

The server sends to the client:

  try { Gson gson = new Gson(); session.getBasicRemote().sendObject( gson.toJson(new ServerMessage(1, "connection accepted"))); } catch (EncodeException e) { // TODO Auto-generated catch block e.printStackTrace(); } 

Clients send to the server:

 try { Gson gson = new Gson(); session.getBasicRemote().sendObject( gson.toJson(new ClientMessage(1, "FirstName"))); } catch (EncodeException e) { // TODO Auto-generated catch block e.printStackTrace(); } 

Clients send a message using the MessageEncoder class, while the server has two encoders and decoders, including TextStreamMessageEncoder or decoder and MessageEncoder or decoder. So, which decoder will be used when the client sends a message to the server?

+6
source share
2 answers

According to the first answer, I would like to summarize it as bellows:

Create two types of encoders and decoders, including Text and BinaryStream.

 public class JsonMessageEncoder implements Encoder.Text<JsonWrapper> { public String encode(JsonWrapper jsonWrapper) throws EncodeException { return jsonWrapper.getJson().toString(); } } public class JsonMessageDecoder implements Decoder.Text<JsonWrapper> { public JsonWrapper decode(String s) throws DecodeException { JsonObject json = Json.createReader(new StringReader(s)).readObject(); System.out.println("JsonWrapper decode: "+json); return new JsonWrapper(json); } public boolean willDecode(String s) { // TODO Auto-generated method stub try { Json.createReader(new StringReader(s)).read(); return true; } catch (JsonException ex) { ex.printStackTrace(); return false; } } } public class BinaryStreamMessageEncoder implements Encoder.BinaryStream<BinaryMessage>{ public void encode(BinaryMessage object, OutputStream os) throws EncodeException, IOException { ObjectOutput objectOutput = new ObjectOutputStream(os); objectOutput.writeObject(object); } } public class BinaryStreamMessageDecoder implements Decoder.BinaryStream<BinaryMessage>{ public BinaryMessage decode(InputStream is) throws DecodeException, IOException { ObjectInput objectInput = new ObjectInputStream(is); try { BinaryMessage binaryMessage= (BinaryMessage) objectInput.readObject(); return binaryMessage; } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } } 

Now add these encoders and decoders to the client and server endpoints.

 @ClientEndpoint(decoders = { JsonMessageDecoder.class, BinaryStreamMessageDecoder.class}, encoders = { JsonMessageEncoder.class, BinaryStreamMessageEncoder.class }) public class ChatClientEndPoint { @OnMessage public void onMessage(JsonWrapper message, Session session) { logger.info("JsonWrapper onMessage: " + session.getId()); if (this.messageHandler != null) this.messageHandler.handleMessage(message); } @OnMessage public void onMessage(BinaryMessage message, Session session) { logger.info("BinaryMessage onMessage: " + session.getId()); if (this.messageHandler != null) this.messageHandler.handleMessage(message); } } @ServerEndpoint(value = "/subscribe", decoders = { JsonMessageDecoder.class, BinaryStreamMessageDecoder.class}, encoders = { JsonMessageEncoder.class,BinaryStreamMessageEncoder.class }) public class ChatServerEndPoint { @OnMessage public void onMessage(JsonWrapper message, Session session) { logger.info("JsonWrapper onMessage: " + session.getId()); // logger.info("onMessage: " + message.toString()); Gson gson = new Gson(); ClientMessage clientMessage = gson.fromJson(message.getJson().toString(), ClientMessage.class); System.out.println(clientMessage.toString()); } @OnMessage public void onMessage(BinaryMessage message, Session session) { logger.info("BinaryMessage onMessage: " + session.getId()); System.out.println(message.toString()); } } 

Clients send a message to the server:

 try { session.getBasicRemote().sendObject(new BinaryMessage("Binary Message")); } catch (EncodeException e) { // TODO Auto-generated catch block e.printStackTrace(); } 

The server sends a message to the client:

 try { session.getBasicRemote().sendObject( gson.toJson(new ServerMessage(1, "connection accepted"))); } catch (EncodeException e) { // TODO Auto-generated catch block e.printStackTrace(); } 

In the example: We use two @OnMessage methods for each endpoint, where one is for the Text type and the other is for the BinaryStream decoder. The client and server send different types of messages to each other, where the client sends a BinaryMessage, which has one String attribute, and the server sends a Json Object. Thus, the runtime will determine what type of decoder and encoder will be used for communication.

Output Client:

JsonWrapper decode: {"id": 1, "message": "connection accepted"}

ServerMessage [id = 1, message = connection accepted]

Output server:

BinaryMessage [name = binary message]

0
source

All Articles