Chapter 9. Configuring JWS Client-Server Communication with WebSocket

9.1. About WebSocket

WebSocket is a web technology that provides bi-directional, full duplex messages to be instantly distributed between a client and server over a single TCP socket connection. A full duplex communication allows two-way communication simultaneously.

The container provides an implementation of the WebSockets 1.0 JSR 356 API. To use the API, you must run Java 7 or later, and configure the APR or NIO2 HTTP/1.1 connectors of the web container.

JSR 356 is the standard for WebSocket API for Java. Developers can use the JSR 356 API for creating WebSocket applications independent of the implementation. The WebSocket API is purely event driven.

Developers can use the JSR 356 Java API for WebSocket to integrate WebSockets in applications on the server side as well as on the client side. Tomcat 7 and 8 implement the WebSocket protocol, which adheres to JSR-356 standard.

A Java client uses a JSR 356-compliant client implementation to connect to a WebSocket server. For web clients, WebSocket JavaScript API can be used to communicate with WebSocket server. The only difference between a WebSocket client and a WebSocket server is the method in which they are connected. A WebSocket client is a WebSocket point from which the connection to a peer originates. A WebSocket server is WebSocket endpoint which is already published and awaits connections from peers.

Some examples where WebSocket can be used include banking, chat, multiplayer, and social networking applications.

9.2. Implementing WebSocket on Tomcat

Configuring WebSocket on Tomcat requires individual configuration of the following:

9.2.1. Configuring Write Timeout

You can change the write timeout in blocking mode by using the org.apache.tomcat.websocket.BLOCKING_SEND_TIMEOUT property. The property accepts values in milliseconds. The default value is 20000 (20 seconds).

9.2.2. Configuring Incoming Binary Messages

To configure incoming binary messages, MessageHandler.Partial must be defined. If MessageHandler.Partial is not defined, then incoming binary messages must be buffered so that the entire message is delivered in a single call to MessageHandler.Whole.

The default buffer size for binary messages is 8192 bytes. You can change the buffer size for a web application by changing the value of the servlet context initializing parameter org.apache.tomcat.websocket.binaryBufferSize.

9.2.3. Configuring Incoming Text Messages

To configure incoming text messages, MessageHandler.Partial must be defined. If MessageHandler.Partial is not defined then incoming text messages must be buffered so that the entire message is delivered in a single call to MessageHandler.Whole.

The default buffer size for text messages is 8192 bytes. You can change the buffer size for a web application by changing the value of the servlet context initializing parameter org.apache.tomcat.websocket.textBufferSize.

9.2.4. Configuring Additional Programmatic Deployment

The Java WebSocket 1.0 specification does not allow programmatic deployment after the first endpoint has started a WebSocket handshake. However, Tomcat by default allows additional programmatic deployment. Additional programmatic deployment can be done by using the servlet context initialization parameter org.apache.tomcat.websocket.noAddAfterHandshake.

Set the system property org.apache.tomcat.websocket.STRICT_SPEC_COMPLIANCE to true to change the default setting.

9.2.5. Configuring Callbacks for Asynchronous Writes

Callbacks for asynchronous writes need to be performed on a different thread to the thread that initiated the write. The container thread pool is not exposed via the Servlet API. Thus the WebSocket implementation has to provide its own thread pool.

The following servlet context initialization parameters control the thread pool:

org.apache.tomcat.websocket.executorCoreSize
The core size of the executor thread pool. If not set, the default of 0 (zero) is used.
org.apache.tomcat.websocket.executorMaxSize
The maximum permitted size of the executor thread pool. If not set, the default of 10 is used.
org.apache.tomcat.websocket.executorKeepAliveTimeSeconds
The maximum time an idle thread will remain in the executor thread pool until it is terminated. If not specified, the default of 60 seconds is used.

9.2.6. Configuring Timeout for IO Operations While Establishing the Connections

The timeout for IO operations while establishing the connections is controlled by the userProperties of the provided javax.websocket.ClientEndpointConfig. You can change timeout by changing the org.apache.tomcat.websocket.IO_TIMEOUT_MS property. The property accepts the values in milliseconds. The default value is 5000 (5 seconds).

To connect a WebSocket client to secure server endpoints, the client SSL configuration is controlled by the userProperties of the provided javax.websocket.ClientEndpointConfig.

The following user properties are supported:

  • org.apache.tomcat.websocket.SSL_CONTEXT
  • org.apache.tomcat.websocket.SSL_PROTOCOLS
  • org.apache.tomcat.websocket.SSL_TRUSTSTORE
  • org.apache.tomcat.websocket.SSL_TRUSTSTORE_PWD

The default truststore password is changeit. The org.apache.tomcat.websocket.SSL_TRUSTSTORE and org.apache.tomcat.websocket.SSL_TRUSTSTORE_PWD properties are ignored if the org.apache.tomcat.websocket.SSL_CONTEXT property is set.