WebSocket How-To
Table of Contents
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.
Production usage
Although the WebSocket implementation does work with any of the HTTP connectors, it is not recommended to the WebSocket with the BIO HTTP connector as the typical uses of WebSocket (large numbers of mostly idle connections) is not a good fit for the HTTP BIO connector which requires that one thread is allocated per connection regardless of whether or not the connection is idle.
It has been reported (56304) that Linux can take large numbers of
minutes to report dropped connections. When using WebSocket with the BIO HTTP
connector this can result in threads blocking on writes for this period. This is
likely to be undesirable. The time taken for the connection to be reported as
dropped can be reduced by using the kernel network parameter
/proc/sys/net/ipv4/tcp_retries2
. Alternatively, one of the other
HTTP connectors may be used as they utilise non-blocking IO enabling Tomcat to
implement its own timeout mechanism to handle these cases.
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
.
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.
The Java WebSocket 1.0 specification requires that callbacks for asynchronous writes are performed on a different thread to the thread that initiated the write. Since the container thread pool is not exposed via the Servlet API, the WebSocket implementation has to provide its own thread pool. This thread pool is controlled by the following servlet context initialization parameters:
org.apache.tomcat.websocket.executorCoreSize
: The core size of the executor thread pool. If not set, the default of 0 (zero) is used. Note that the maximum permitted size of the executor thread pool is hard coded toInteger.MAX_VALUE
which effectively means it is unlimited.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.
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.