Skip to content

Latest commit

 

History

History
194 lines (155 loc) · 5.24 KB

File metadata and controls

194 lines (155 loc) · 5.24 KB

WebSockets

WebSockets are added using the javadoc:Router[ws] method:

WebSocket
{
  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)
    });
  });
}
Kotlin
{
  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)
    }
  }
}
  1. Register a WebSocket handler.

  2. On connection (open), send a message back to the client. This is also a good place to initialize resources.

  3. On receiving a new message, send a response back to the client.

  4. The WebSocket is about to close. You must free/release any acquired resources here.

  5. 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.

Accessing Context
{
  ws("/ws/{key}", (ctx, configurer) -> {
    String key = ctx.path("key").value();           // (1)
    String foo = ctx.session().get("foo").value();  // (2)
    // ...
  });
}
Kotlin
{
  ws("/ws/{key}") { ctx, configurer ->
    val key = ctx.path("key").value()               // (1)
    val foo = ctx.session().get("foo").value()      // (2)
    // ...
  }
}
  1. Access a path variable (key).

  2. Access a session variable (foo).

Structured Data

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.

JSON Example
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)
    });
  });
}
Kotlin
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)
    }
  }
}
  1. Install the Jackson module (required for JSON decoding/encoding).

  2. Parse and decode the incoming message to a MyObject.

  3. Encode myobject as 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:

Explicit Content Types
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);
}
Kotlin
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)
}

Options

Connection Timeouts

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:

application.conf
websocket.idleTimeout = 1h

See the Typesafe Config documentation for the supported duration format.

Max Size

The maximum message size is set to 128K by default. You can override it using the websocket.maxSize property:

application.conf
websocket.maxSize = 128K

See the Typesafe Config documentation for the supported size in bytes format.