Undertow is an open-source lightweight, flexible and performant Java server, they say. I can confirm that it’s
- lightweight: just have a look at those few lines of code to start a server and 1MB core JAR
- flexible: always feel free to provide your own implementations or use Undertow helpers to delegate usual server glue code to a more specific implementation you provide
I didn’t check or compare performance. It is the default server implementation of Wildfly Application Server and sponsored by JBoss.
Default undertow bootstrapping: dynamically initializes thread pools, buffers, etc. according to your hardware resources.
Undertow undertow = Undertow.builder()
// listen
.addHttpListener(8080, "localhost")
// let's add a http and a websocket endpoint
.setHandler(
// combines many `HttpHandler` by path
Handlers.path()
// any path: "/gate/http/**"
.addPrefixPath("/gate/http", new MyHttpHandler())
// exact path "/gate/ws"
.addExactPath("/gate/ws", Handlers.websocket(new MyWebsocketCallback()))
)
.build();
undertow.start();
HttpHandler::handleRequest
is to be invoked by one of the IO threads which should immediately return, thus either complete exchange or delay processing via dispatch.
MyHttpHandler.java
class MyHttpHandler implements HttpHandler {
@Override
public void handleRequest(final HttpServerExchange exchange)
throws Exception
{
// dispatch to non-io threads
if (exchange.isInIoThread()) {
exchange.dispatch(this);
return;
}
// in worker thread
// implement here ...
}
}
Websocket endpoints can be set up via Handlers.websocket(callback)
taking a WebSocketConnectionCallback
we have to implement and returns the corresponding HttpHandler
.
MyWebsocketCallback.java
class MyWebsocketCallback implements WebSocketConnectionCallback {
@Override
public void onConnect(
WebSocketHttpExchange exchange,
WebSocketChannel webSocketChannel
) {
// per default channel is not active
// and will not receive anything
webSocketChannel
.getReceiveSetter()
.set(new MyReceiveListener());
webSocketChannel.resumeReceives();
}
}
At least implement MyReceiveListener
and override those methods you’re interested in.
MyReceiveListener.java
class MyReceiveListener extends AbstractReceiveListener {
@Override
protected void onFullTextMessage(
WebSocketChannel channel,
BufferedTextMessage message
) throws IOException {
WebSockets.sendText(
"you sent: " + message.getData(),
channel,
null
);
}
// onError
// onCloseMessage
// ...
}