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) {
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());
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]