## WebSocket How-To

### Table of Contents

- Overview
- Application development
- Tomcat WebSocket specific configuration

### Overview

Tomcat provides support for WebSocket as defined by RFC 6455.

### Application development

Tomcat implements the Java WebSocket 1.1 API defined by JSR-356.

There are several example applications that demonstrate how the WebSocket API can be used. You will need to look at both the client side HTML and the server side code.

### Tomcat WebSocket specific configuration

Tomcat provides a number of Tomcat specific configuration options for WebSocket. It is anticipated that these will be absorbed into the WebSocket specification over time.

The write timeout used when sending WebSocket messages in blocking mode defaults to 20000 milliseconds (20 seconds). This may be changed by setting the property `org.apache.tomcat.websocket.BLOCKING_SEND_TIMEOUT` in the user properties collection attached to the WebSocket session. The value assigned to this property should be a `Long` and represents the timeout to use in milliseconds. For an infinite timeout, use `-1`.

In addition to the `Session.setMaxIdleTimeout(long)` method which is part of the Java WebSocket API, Tomcat provides greater control of the timing out the session due to lack of activity. Setting the property `org.apache.tomcat.websocket.READ_IDLE_TIMEOUT_MS` in the user properties collection attached to the WebSocket session will trigger a session timeout if no WebSocket message is received for the specified number of milliseconds. Setting the property `org.apache.tomcat.websocket.WRITE_IDLE_TIMEOUT_MS` will trigger a session timeout if no WebSocket message is sent for the specified number of milliseconds. These can be used separately or together, with or without `Session.setMaxIdleTimeout(long)`. If the associated property is not specified, the read and/or write idle timeout will be applied.

If the application does not define a `MessageHandler.Partial` for incoming binary messages, any incoming binary messages must be buffered so the entire message can be delivered in a single call to the registered `MessageHandler.Whole` for binary messages. The default buffer size for binary messages is 8192 bytes. This may be changed for a web application by setting the servlet context initialization parameter `org.apache.tomcat.websocket.binaryBufferSize` to the desired value in bytes.

If the application does not define a `MessageHandler.Partial` for incoming text messages, any incoming text messages must be buffered so the entire message can be delivered in a single call to the registered `MessageHandler.Whole` for text messages. The default buffer size for text messages is 8192 bytes. This may be changed for a web application by setting the servlet context initialization parameter `org.apache.tomcat.websocket.textBufferSize` to the desired value in bytes.

The Java WebSocket specification 1.0 does not permit programmatic deployment after the first endpoint has started a WebSocket handshake. By default, Tomcat continues to permit additional programmatic deployment. This behavior is controlled by the `org.apache.tomcat.websocket.noAddAfterHandshake` servlet context initialization parameter. The default may be changed by setting the `org.apache.tomcat.websocket.STRICT_SPEC_COMPLIANCE` system property to `true` but any explicit setting on the servlet context will always take priority.

When using the WebSocket client to connect to server endpoints, the timeout for IO operations while establishing the connection is controlled by the `userProperties` of the provided `javax.websocket.ClientEndpointConfig`. The property is `org.apache.tomcat.websocket.IO_TIMEOUT_MS` and is the timeout as a `String` in milliseconds. The default is 5000 (5 seconds).

When using the WebSocket client to connect 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`.

If the `org.apache.tomcat.websocket.SSL_CONTEXT` property is set then the `org.apache.tomcat.websocket.SSL_TRUSTSTORE` and `org.apache.tomcat.websocket.SSL_TRUSTSTORE_PWD` properties will be ignored.

For secure server end points, host name verification is enabled by default. To bypass this verification (not recommended), it is necessary to provide a custom `SSLContext` via the `org.apache.tomcat.websocket.SSL_CONTEXT` user property. The custom `SSLContext` must be configured with a custom `TrustManager` that extends `javax.net.ssl.X509ExtendedTrustManager`. The desired verification (or lack of verification) can then be controlled by appropriate implementations of the individual abstract methods.

When using the WebSocket client to connect to server endpoints, the number of HTTP redirects that the client will follow is controlled by the `userProperties` of the provided `javax.websocket.ClientEndpointConfig`. The property is <ocde>org.apache.tomcat.websocket.MAX_REDIRECTIONS</ocde>. The default value is 20. Redirection support can be disabled by configuring a value of zero.

When using the WebSocket client to connect to a server endpoint that requires BASIC or DIGEST authentication, the following user properties must be set:

- `org.apache.tomcat.websocket.WS_AUTHENTICATION_USER_NAME`
- `org.apache.tomcat.websocket.WS_AUTHENTICATION_PASSWORD`

Optionally, the WebSocket client can be configured only to send credentials if the server authentication challenge includes a specific realm by defining that realm in the optional user property:

- `org.apache.tomcat.websocket.WS_AUTHENTICATION_REALM`

When using the WebSocket client to connect to a server endpoint via a forward proxy (also known as a gateway) that requires BASIC or DIGEST authentication, the following user properties must be set:

- `org.apache.tomcat.websocket.WS_PROXY_AUTHENTICATION_USER_NAME`
- `org.apache.tomcat.websocket.WS_PROXY_AUTHENTICATION_PASSWORD`

Optionally, the WebSocket client can be configured only to send credentials if the server authentication challenge includes a specific realm by defining that realm in the optional user property:

- `org.apache.tomcat.websocket.WS_PROXY_AUTHENTICATION_REALM`