Skip to content

Web Socket routing

Miere Teixeira edited this page Oct 2, 2017 · 4 revisions

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. [block:code] { "codes": [ { "code": "import io.undertow.websockets.core.CloseMessage;\nimport kikaha.urouting.api.*;\n\n@WebSocket( "chat/{room-id}" )\npublic class ChatResource {\n\n\t@OnOpen\n\tpublic void onOpen(\n\t\t@HeaderParam( "SESSION" ) final String sessionId ) {\n\t\tSystem.out.println( sessionId );\n\t}\n\n\t@OnError\n\tpublic void onError( final Throwable cause ) {\n\t\tSystem.err.println( cause.getMessage() );\n\t}\n\n\t@OnClose\n\tpublic void onClose( final CloseMessage cm ) {\n\t\tSystem.out.println( cm.getReason() );\n\t}\n}", "language": "java" } ] } [/block]

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. [block:code] { "codes": [ { "code": "import io.undertow.websockets.core.CloseMessage;\nimport kikaha.core.modules.websocket.WebSocketSession;\nimport kikaha.urouting.api.*;\n\n@WebSocket( "chat/{room-id}" )\npublic class ChatResource {\n\n\t@OnMessage\n\tpublic void onMessage( WebSocketSession session, String message ) {\n\t\tsession.broadcast( session.userPrincipal() + " just sent: " + message );\n\t}\n\n\t@OnOpen\n\tpublic void onOpen( WebSocketSession session ) {\n\t\tsession.broadcast( session.userPrincipal() + " has entered into the chat room" );\n\t}\n\n\t@OnError\n\tpublic void onError( final Throwable cause ) {\n\t\tSystem.err.println( cause.getMessage() );\n\t}\n\n\t@OnClose\n\tpublic void onClose( WebSocketSession session, CloseMessage cm ) {\n\t\tsession.broadcast( session.userPrincipal() + " left the chat room" );\n\t}\n}", "language": "java" } ] } [/block]

WebSocketSession API

Some data provided by 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
Clone this wiki locally