javaee7-samples icon indicating copy to clipboard operation
javaee7-samples copied to clipboard

How to use Encoder/Decoder.TextStream correctly in Java WebSocket?

Open ngoduyhoa opened this issue 12 years ago • 0 comments

Hi,

I did not find a simple example of using TextStream or BinaryStream. Thus, I am trying to write a simple one to understand them better. The idea is simple. I write annotation based Server and Client Websocket by using Glassfish and Tyrus API. The message is encoded/decoded by using TextStream. When client connect to the server, the server send a JSON object to tell the client its session ID.

Unfortunately, my program does not work :(. But if I use encoder/decoder by Text<>, it works perfectly. I don't understand much about the different configuration for Text and TextStream.

Here are the codes:


ServerEnpoint (WSServer.java) will be exported in WSServer.war

@ServerEndpoint(value = "/test", encoders = {Msg.MsgEncoder.class}, decoders = {Msg.MsgDecoder.class})
public class WSServer{
     @OnOpen
     public void handleConnection(Session session){
        String  notification    =   "New connection : " + session.getId();
        System.out.println(notification);
        try {
            session.getBasicRemote().sendObject(new Msg(notification));
        } catch (Exception e) {
             e.printStackTrace();
        }
    }
}

ClientEndpoint (WSClient.java):

@ClientEndpoint(encoders = {Msg.MsgEncoder.class}, decoders = {Msg.MsgDecoder.class})
public class WSClient{  
      @OnMessage
      public void handleMessage(Msg msg){
      System.out.println(msg.getMessage());
 }

 public static void main(String[] args){
     WebSocketContainer  container   =   ContainerProvider.getWebSocketContainer();      
     String  uri =   "ws://localhost:8080/WSServer/test";        
        try {
            Session session =   container.connectToServer(WSClient.class, URI.create(uri));         
            while (session.isOpen()) {              
            Thread.sleep(1000);
            session.close();
            }           
        } catch (Exception e) {         
            e.printStackTrace();            
        } 
      }
}

Class Msg and its encoder/decoder

public class Msg { String message;

public Msg(String message) {
    super();
    this.message = message;
}

public String getMessage() {
    return message;
}

public static class MsgEncoder implements Encoder.TextStream<Msg>{
    @Override
    public void encode(Msg msg, Writer writer) throws EncodeException,IOException {
        JsonWriter  jWriter =   Json.createWriter(writer);
        JsonObject  jsonObj =   Json.createObjectBuilder().add("message", msg.getMessage()).build();
        jWriter.writeObject(jsonObj);
    }
}

  public static class MsgDecoder implements Decoder.TextStream<Msg>{
    @Override
    public Msg decode(Reader reader) throws DecodeException, IOException {
        JsonReader  jReader =   Json.createReader(reader);
        JsonObject  jsonObj =   jReader.readObject();
        String  message =   jsonObj.getString("message");
        Msg msg =   new Msg(message);           
        return msg;
    }
   }
}

After deploying WSServer.war by GlassFish 4 server, I run WSClient but it does not print anything.

In the same way, instead of using Encoder/Decoder.TextStream<>, I use Encoder/Decoder.Text<>, the client will print the message "New connection : 087c959f-fae2-4d0a-97cb-727ceec6e2e3", which is what I expect to see.

I have been trying to understand the difference between using Text<> and TextStream<> to fix the problem without luck :(. Could you please tell me what I have done incorrectly in my code? Thank you.

ngoduyhoa avatar Oct 22 '13 14:10 ngoduyhoa