Web Sockets

What are web sockets

WebSocket is a protocol providing full-duplex communication channels over a single TCP connection. The WebSocket protocol was standardized by the IETF as RFC 6455 in 2011, and the WebSocket API in Web IDL is being standardized by the W3C.

When a client (Browser) wants to establish a connection with a server using a web socket, it starts by a handshake. Once done, a tunnel connects the client and the server. So, the server can push data to the client and vice-versa. Such a mechanism paves the way to more reactive web applications, where notifications and up to date data are pushed to the client without having to rely on ajax or long polling.

WebSocket are identified using urls. These urls starts either by ws:// or wss://+.

Receiving data

A controller willing to listen for data sent by clients on a specific web socket has to use the @onMessage annotation:

include::{sourcedir}/controllers/websockets/WebSocketController.java[tags=reception]

Every time a client sends data on ws:///localhost:9000/socket, the callback is called. Notice the @Body annotation parsing the message to the parameter’s type (here as String). The @Body annotation works the same way as in action methods:

include::{sourcedir}/controllers/websockets/WebSocketController.java[tags=receptionWithJson]

The web socket URI provided in the @OnMessage annotation’s parameter can contain a dynamic part as for action methods:

include::{sourcedir}/controllers/websockets/WebSocketController.java[tags=parameter]

The @Parameter annotation let you retrieve the dynamic parts.

Finally, you can identify the client sending the data using a special parameter named client:

include::{sourcedir}/controllers/websockets/WebSocketController.java[tags=client]
Important
Be aware that the client identifier changes if the user disconnects and reconnects.

Send data to a specific client

Now that we can receive data from the client, it would be nice to push data to it.

include::{sourcedir}/controllers/websockets/WebSocketController.java[tags=send]

Two important things here:

  • The publisher is a service (provided by Wisdom) responsible for sending data to web socket clients.

  • We use the send method pushing data to a specific client

So, the previous snippet would produce such a kind of conversation:

client >>> hello >>> server
client <<< HELLO <<< server

Send data to all clients

The previous example sends data specifically to one client. However, data can be broadcast to all clients connected to a specific web socket:

include::{sourcedir}/controllers/websockets/WebSocketController.java[tags=publish]

The main difference is the usage of the publish method instead of send.

Sending Json or binary data

So far, we have only sent String messages. However, you can send or publish binary data too:

include::{sourcedir}/controllers/websockets/WebSocketController.java[tags=binary]

By the way, notice that this method is not an OnMessage callback, but a method executed every 5 seconds.

You can also send JSON messages directly too:

include::{sourcedir}/controllers/websockets/WebSocketController.java[tags=json]

Being notified of client connections and disconnections

In addition to OnMessage, there are two other annotations useful to know when clients connect and disconnect from the listened socket:

include::{sourcedir}/controllers/websockets/WebSocketController.java[tags=notification]

@Opened and @Closed callbacks can also use URI with dynamic parts too. To retrieve the identifier of the client, just use @Parameter("client").