WebSockets are added using the javadoc:Router[ws] method:
{
ws("/ws", (ctx, configurer) -> { // (1)
configurer.onConnect(ws -> {
ws.send("Connected"); // (2)
});
configurer.onMessage((ws, message) -> {
ws.send("Got " + message.value()); // (3)
});
configurer.onClose((ws, statusCode) -> {
// Clean up resources (4)
});
configurer.onError((ws, cause) -> {
// Handle exceptions (5)
});
});
}{
ws("/ws") { ctx, configurer -> // (1)
configurer.onConnect { ws ->
ws.send("Connected") // (2)
}
configurer.onMessage { ws, message ->
ws.send("Got " + message.value()) // (3)
}
configurer.onClose { ws, statusCode ->
// Clean up resources (4)
}
configurer.onError { ws, cause ->
// Handle exceptions (5)
}
}
}-
Register a WebSocket handler.
-
On connection (open), send a message back to the client. This is also a good place to initialize resources.
-
On receiving a new message, send a response back to the client.
-
The WebSocket is about to close. You must free/release any acquired resources here.
-
The WebSocket encountered an exception. Useful for logging the error or providing an alternative response if the socket is still open.
You are free to access the HTTP context from the WebSocket configurer or callbacks, but it is forbidden to modify the HTTP context or produce an HTTP response from it.
{
ws("/ws/{key}", (ctx, configurer) -> {
String key = ctx.path("key").value(); // (1)
String foo = ctx.session().get("foo").value(); // (2)
// ...
});
}{
ws("/ws/{key}") { ctx, configurer ->
val key = ctx.path("key").value() // (1)
val foo = ctx.session().get("foo").value() // (2)
// ...
}
}-
Access a path variable (
key). -
Access a session variable (
foo).
Structured data (like JSON) is supported using the Value API and the javadoc:WebSocket[render, java.lang.Object] method.
To use structured messages, you need a registered javadoc:MessageDecoder[] and javadoc:MessageEncoder[]. In the following example, both are provided by the JacksonModule.
import io.jooby.jackson.JacksonModule;
{
install(new JacksonModule()); // (1)
ws("/ws", (ctx, configurer) -> {
configurer.onMessage((ws, message) -> {
MyObject myobject = message.to(MyObject.class); // (2)
ws.render(myobject); // (3)
});
});
}import io.jooby.jackson.JacksonModule
{
install(JacksonModule()) // (1)
ws("/ws") { ctx, configurer ->
configurer.onMessage { ws, message ->
val myobject = message.to<MyObject>() // (2)
ws.render(myobject) // (3)
}
}
}-
Install the Jackson module (required for JSON decoding/encoding).
-
Parse and decode the incoming message to a
MyObject. -
Encode
myobjectas JSON and send it to the client.
Alternatively, you can explicitly tell the WebSocket which decoder/encoder to use by specifying the consumes and produces attributes:
import io.jooby.jackson.JacksonModule;
{
install(new JacksonModule()); // (1)
ws("/ws", (ctx, configurer) -> {
configurer.onMessage((ws, message) -> {
MyObject myobject = message.to(MyObject.class); // (2)
ws.render(myobject); // (3)
});
})
.consumes(MediaType.json)
.produces(MediaType.json);
}import io.jooby.jackson.JacksonModule
{
install(JacksonModule()) // (1)
ws("/ws") { ctx, configurer ->
configurer.onMessage { ws, message ->
val myobject = message.to<MyObject>() // (2)
ws.render(myobject) // (3)
}
}.consumes(MediaType.json)
.produces(MediaType.json)
}Jooby automatically times out idle connections that have no activity after 5 minutes. You can control this behavior by setting the websocket.idleTimeout property in your configuration file:
websocket.idleTimeout = 1hSee the Typesafe Config documentation for the supported duration format.
The maximum message size is set to 128K by default. You can override it using the websocket.maxSize property:
websocket.maxSize = 128KSee the Typesafe Config documentation for the supported size in bytes format.