Web Socket routing - Skullabs/kikaha GitHub Wiki
WebSocket Routing
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. Undertow provides support for Websockets out of the box. Undertow core provides a XNIO based API, which uses the Xnio Channel interface to provide access to the web socket at a low level.
Most users will want a higher level interface than this and Undertow provides a JSR-356 implementation through the undertow-websocket-jsr
. It is quite useful and has awesome performance, but it stills depends on Servlet API. As Servlet containers hurts Kikaha's philosophy due to its complexity, micro Routing API also offers a tiny layer for dealing with Web Socket Resources.
Note: to use WebSocket routing be sure to include the uRouting API dependency on your project.
Creating my first first web socket endpoint
The bellow sample shows how to listen to messages sent in a chat room.
import kikaha.urouting.api.*;
@WebSocket( "chat/{room-id}" )
public class ChatResource {
@OnMessage
public void onMessage(
@PathParam("room-id") final Long id,
final String message ) {
System.out.println( id + ":" + message );
}
}
Notes:
- The string object message is the message received from the WebSocket client
- The Long object id was extracted from URI path, once it is annotated with
@PathParam
annotation - It is also possible to extract data from Headers using the
@HeaderParam
annotation the same way you use for other ordinary HTTP requests.
Listening to the Web Socket events
Similarly to JSR-356, you are able to listen to any web socket events (on error
, on open
and on close
) using annotations.
import io.undertow.websockets.core.CloseMessage;
import kikaha.urouting.api.*;
@WebSocket( "chat/{room-id}" )
public class ChatResource {
@OnOpen
public void onOpen(
@HeaderParam( "SESSION" ) final String sessionId ) {
System.out.println( sessionId );
}
@OnError
public void onError( final Throwable cause ) {
System.err.println( cause.getMessage() );
}
@OnClose
public void onClose( final CloseMessage cm ) {
System.out.println( cm.getReason() );
}
}
Sending messages to other peers
Kikaha wrapped the Undertow WebSocket session in a WebSocketSession
instance. This session instance is able to send messages to other peers, or even broadcast message to them. You can inject the a WebSocketSession
instance wherever the event method you need.
import io.undertow.websockets.core.CloseMessage;
import kikaha.core.modules.websocket.WebSocketSession;
import kikaha.urouting.api.*;
@WebSocket( "chat/{room-id}" )
public class ChatResource {
@OnMessage
public void onMessage( WebSocketSession session, String message ) {
session.broadcast( session.userPrincipal() + " just sent: " + message );
}
@OnOpen
public void onOpen( WebSocketSession session ) {
session.broadcast( session.userPrincipal() + " has entered into the chat room" );
}
@OnError
public void onError( final Throwable cause ) {
System.err.println( cause.getMessage() );
}
@OnClose
public void onClose( WebSocketSession session, CloseMessage cm ) {
session.broadcast( session.userPrincipal() + " left the chat room" );
}
}
A brief description of some methods available on WebSocketSession:
- WebSocketSession.broadcast - sends messages to every peer on the same "room"
- WebSocketSession.send( "message" ).to( peer ) - sends messages to a specific peer
- WebSocketSession.getUserPrincipal() - returns the current logged in used
- WebSocketSession.getRequestHeaders() - returns all headers sent by the request
- WebSocketSession.getRequestParameters() - returns all parameters sent by the request