Processing Text and Binary (Blob, ArrayBuffer, ArrayBufferView) Payload in WebSocket - (TOTD #185)
Posted
by arungupta
on Oracle Blogs
See other posts from Oracle Blogs
or by arungupta
Published on Mon, 12 Nov 2012 07:00:00 +0000
Indexed on
2012/11/12
11:10 UTC
Read the original article
Hit count: 241
/General
The WebSocket API defines different
send(xxx)
methods that can be used
to send text and binary data. This Tip Of The
Day (TOTD) will show how to send and receive text and binary
data using WebSocket.TOTD #183 explains how to get started with a WebSocket endpoint using GlassFish 4. A simple endpoint from that blog looks like:
@WebSocketEndpoint("/endpoint") public class MyEndpoint { public void receiveTextMessage(String message) { . . . } }A message with the first parameter of the type
String
is invoked when a text payload is received. The payload of the
incoming WebSocket frame is mapped to this first parameter.An optional second parameter,
Session
, can be
specified to map to the "other end" of this conversation. For
example:public void receiveTextMessage(String message, Session session) { . . . }The return type is
void
and that means no response is
returned to the client that invoked this endpoint. A response may be
returned to the client in two different ways. First, set the return
type to the expected type, such as:public String receiveTextMessage(String message) { String response = . . .In this case a text payload is returned back to the invoking endpoint.
. . .
return response; }
The second way to send a response back is to use the mapped session to send response using one of the
sendXXX
methods in Session
,
when and if needed.public void receiveTextMessage(String message, Session session) { . . . RemoteEndpoint remote = session.getRemote(); remote.sendString(...); . . . remote.sendString(...); . . . remote.sendString(...); }This shows how duplex and asynchronous communication between the two endpoints can be achieved. This can be used to define different message exchange patterns between the client and server.
The WebSocket client can send the message as:
websocket.send(myTextField.value);where
myTextField
is a text field in the web page.Binary payload in the incoming WebSocket frame can be received if
ByteBuffer
is used as the first parameter of the method signature. The endpoint
method signature in that case would look like:public void receiveBinaryMessage(ByteBuffer message) { . . . }From the client side, the binary data can be sent using
Blob
,
ArrayBuffer
, and ArrayBufferView
. Blob is
a just raw data and the actual interpretation is left to the
application. ArrayBuffer
and ArrayBufferView
are defined in the TypedArray
specification and are designed to send binary data using
WebSocket. In short, ArrayBuffer
is a fixed-length
binary buffer with no format and no mechanism for accessing its
contents. These buffers are manipulated using one of the views
defined by one of the subclasses of ArrayBufferView
listed below:Int8Array
(signed 8-bit integer orchar
)
Uint8Array
(unsigned 8-bit integer orunsigned char
)
Int16Array
(signed 16-bit integer orshort
)
Uint16Array
(unsigned 16-bit integer orunsigned short
)Int32Array
(signed 32-bit integer orint
)Uint32Array
(unsigned 16-bit integer orunsigned int
)Float32Array
(signed 32-bit float orfloat
)Float64Array
(signed 64-bit float ordouble
)
ArrayBuffer
with
a view defined by a subclass of ArrayBufferView
or a
subclass of ArrayBufferView
itself.The WebSocket client can send the message using Blob as:
blob = new Blob([myField2.value]);
websocket.send(blob);
where
myField
2 is a text field in the web page.The WebSocket client can send the message using
ArrayBuffer
as:var buffer = new ArrayBuffer(10);A concrete implementation of receiving the binary message may look like:
var bytes = new Uint8Array(buffer);
for (var i=0; i<bytes.length; i++) {
bytes[i] = i;
}
websocket.send(buffer);
@WebSocketMessage
public void echoBinary(ByteBuffer data, Session session) throws IOException {
System.out.println("echoBinary: " + data);
for (byte b : data.array()) {
System.out.print(b);
}
session.getRemote().sendBytes(data);
}
This method is just printing the binary data for verification but you may actually be storing it in a database or converting to an image or something more meaningful.
Be aware of TYRUS-51 if you are trying to send binary data from server to client using method return type.
Here are some references for you:
- JSR 356: Java API for WebSocket - Specification (Early Draft) and Implementation (already integrated in GlassFish 4 promoted builds)
- TOTD #183 - Getting Started with WebSocket in GlassFish
- TOTD #184 - Logging WebSocket Frames using Chrome Developer Tools, Net-internals and Wireshark
- Error handling
- Custom payloads using encoder/decoder
- Interface-driven WebSocket endpoint
- Java client API
- Client and Server configuration
- Security
- Subprotocols
- Extensions
- Other topics from the API
© Oracle Blogs or respective owner