X

Custom Text and Binary Payloads using WebSocket (TOTD #186)

Guest Author


href="https://blogs.oracle.com/arungupta/entry/processing_text_and_binary_payload">
TOTD #185 explained how to process text and binary payloads in
a WebSocket endpoint. In summary, a text payload may be received as


public void receiveTextMessage(String message) {
    . . .
}



And binary payload may be received as:


public void recieveBinaryMessage(ByteBuffer message) {
    . . .
}



As you realize, both of these methods receive the text and binary
data in raw format. However you may like to receive and send the
data using a POJO. This marshaling and unmarshaling can be done in
the method implementation but JSR 356 API provides a cleaner way.
For encoding and decoding text payload into POJO, Decoder.Text
(for inbound payload) and Encoder.Text (for outbound
payload) interfaces need to be implemented.



A sample implementation below shows how text payload consisting of
JSON structures can be encoded and decoded.
public class MyMessage implements Decoder.Text<MyMessage>, Encoder.Text<MyMessage> {
    private JsonObject jsonObject;

    @Override
    public MyMessage decode(String string) throws DecodeException {
        this.jsonObject = new JsonReader(new StringReader(string)).readObject();      
        return this;
    }

    @Override
    public boolean willDecode(String string) {
        return true;
    }

    @Override
    public String encode(MyMessage myMessage) throws EncodeException {
        return myMessage.jsonObject.toString();
    }

public JsonObject getObject() { return jsonObject; }
}

In this implementation, the decode method decodes
incoming text payload to MyMessage, the encode
method encodes MyMessage for the outgoing text
payload, and the willDecode method returns true
or false if the message can be decoded.



The encoder and decoder implementation classes need to be specified
in the WebSocket endpoint as:
@WebSocketEndpoint(value="/endpoint",
encoders={MyMessage.class},
decoders={MyMessage.class})
public class MyEndpoint {
public MyMessage receiveMessage(MyMessage message) {
. . .
}
}

Notice the updated method signature where the application is working
with MyMessage instead of the raw string.



Note that the encoder and decoder implementations just illustrate
the point and provide no validation or exception handling. Similarly
Encooder.Binary and Decoder.Binary
interfaces need to be implemented for encoding and decoding binary
payload.



Here are some references for you:
  • JSR 356:
    Java API for WebSocket - href="http://websocket-spec.java.net/">Specification (href="http://jcp.org/aboutJava/communityprocess/edr/jsr356/index.html">Early
    Draft) and Implementation
    (already integrated in href="http://download.java.net/glassfish/4.0/promoted">GlassFish
    4 promoted builds)
  • href="https://blogs.oracle.com/arungupta/entry/websocket_applications_using_java_jsr">TOTD
    #183 - Getting Started with WebSocket in GlassFish
  • href="https://blogs.oracle.com/arungupta/entry/logging_websocket_frames_using_chrome">TOTD
    #184 - Logging WebSocket Frames using Chrome Developer
    Tools, Net-internals and Wireshark
  • href="https://blogs.oracle.com/arungupta/entry/processing_text_and_binary_payload">TOTD
    #185: Processing Text and Binary (Blob, ArrayBuffer,
    ArrayBufferView) Payload in WebSocket

Subsequent blogs will discuss the following topics (not necessary in
that order) ...
  • Error handling
  • Interface-driven WebSocket endpoint
  • Java client API
  • Client and Server configuration
  • Security
  • Subprotocols
  • Extensions

  • Other topics from the API

Join the discussion

Comments ( 4 )
  • Jan Monday, December 3, 2012

    Glassfish 4 Nightly b65 seems to ignore the ws-protocol. It deploys, but a call to the ws://..../websocket comes back with a 404. It feels like GF doesn't do the protocol upgrade although the WebSocket-checkbox is checked in the http-listener-panel.

    I have the feeling that the Tyrus-part just ain't starting correctly. I've placed a breakpoint on the @WebSocketOpen-method and it is not being executed at all. Do you have a tip?

    thanks

    Jan


  • Arun Gupta Monday, December 3, 2012

    I'm using 64 and that is working fine. In particular, the app described at https://blogs.oracle.com/arungupta/entry/collaborative_whiteboard_using_websocket_in is built using 64.

    Can you try 64 first ? If it works there then file a regression at http://java.net/jira/secure/CreateIssue.jspa?pid=10231&issuetype=1


  • Jan Monday, December 3, 2012

    Yes, the nightly (!) 65 build seems to be corrupt. It work in promoted build 64.

    Could you also blog about the threading-model behind WebSockets in Glassfish? How many request-threads do you need etc? What about scaling in the cloud? Can you send messages from more than one node in a cluster, or how does that function? (scenario: my websocket is in server A but server B has a message for me, but I am not in his peerslist)

    Thanks,

    Jan


  • Arun Gupta Monday, December 3, 2012

    Jan, definitely a bug in that case. Can you file an issue with P1 ? This seems to be a regression.

    Thanks for suggestions on future blogs, will add them to my TODO list.


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.