<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<!DOCTYPE document [
  <!ENTITY project SYSTEM "project.xml">
]>
<document url="web-socket-howto.html">

    &project;

    <properties>
      <title>WebSocket How-To</title>
    </properties>

<body>

<section name="Table of Contents">
<toc/>
</section>

<section name="Overview">
<p>Tomcat provides support for WebSocket as defined by
   <a href="https://tools.ietf.org/html/rfc6455">RFC 6455</a>.</p>
</section>

<section name="Application development">
<p>Tomcat implements the Java WebSocket 1.1 API defined by <a
   href="https://www.jcp.org/en/jsr/detail?id=356">JSR-356</a>.</p>

<p>There are several example applications that demonstrate how the WebSocket API
   can be used. You will need to look at both the client side <a
   href="https://github.com/apache/tomcat/tree/9.0.x/webapps/examples/websocket">
   HTML</a> and the server side <a
   href="https://github.com/apache/tomcat/tree/9.0.x/webapps/examples/WEB-INF/classes/websocket">
   code</a>.</p>
</section>

<section name="Tomcat WebSocket specific configuration">

<p>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.</p>

<p>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 <code>org.apache.tomcat.websocket.BLOCKING_SEND_TIMEOUT</code>
   in the user properties collection attached to the WebSocket session. The
   value assigned to this property should be a <code>Long</code> and represents
   the timeout to use in milliseconds. For an infinite timeout, use
   <code>-1</code>.</p>

<p>The time Tomcat waits for a peer to send a WebSocket session close message
   after Tomcat has sent a close message to the peer defaults to 30000
   milliseconds (30 seconds). This may be changed by setting the property
   <code>org.apache.tomcat.websocket.SESSION_CLOSE_TIMEOUT</code> in the user
   properties collection attached to the WebSocket session. The value assigned
   to this property should be a <code>Long</code> and represents the timeout to
   use in milliseconds. Values less than or equal to zero will be ignored.</p>

<p>The write timeout Tomcat uses when writing a session close message when the
   close is abnormal defaults to 50 milliseconds. This may be changed by setting
   the property
   <code>org.apache.tomcat.websocket.ABNORMAL_SESSION_CLOSE_SEND_TIMEOUT</code>
   in the user properties collection attached to the WebSocket session. The
   value assigned to this property should be a <code>Long</code> and represents
   the timeout to use in milliseconds. Values less than or equal to zero will be
   ignored.</p>

<p>In addition to the <code>Session.setMaxIdleTimeout(long)</code> 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
   <code>org.apache.tomcat.websocket.READ_IDLE_TIMEOUT_MS</code> 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
   <code>org.apache.tomcat.websocket.WRITE_IDLE_TIMEOUT_MS</code> 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
   <code>Session.setMaxIdleTimeout(long)</code>. If the associated property is
   not specified, the read and/or write idle timeout will be applied.</p>

<p>If the application does not define a <code>MessageHandler.Partial</code> 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
   <code>MessageHandler.Whole</code> 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
   <code>org.apache.tomcat.websocket.binaryBufferSize</code> to the desired
   value in bytes.</p>

<p>If the application does not define a <code>MessageHandler.Partial</code> 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
   <code>MessageHandler.Whole</code> 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
   <code>org.apache.tomcat.websocket.textBufferSize</code> to the desired value
   in bytes.</p>

<p>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
   <code>org.apache.tomcat.websocket.noAddAfterHandshake</code> servlet context
   initialization parameter. The default may be changed by setting the
   <code>org.apache.tomcat.websocket.STRICT_SPEC_COMPLIANCE</code> system
   property to <code>true</code> but any explicit setting on the servlet context
   will always take priority.</p>

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

<p>When using the WebSocket client to connect to secure server endpoints, the
   client SSL configuration is controlled by the <code>userProperties</code>
   of the provided <code>javax.websocket.ClientEndpointConfig</code>. The
   following user properties are supported:</p>
   <ul>
     <li><code>org.apache.tomcat.websocket.SSL_CONTEXT</code></li>
     <li><code>org.apache.tomcat.websocket.SSL_PROTOCOLS</code></li>
     <li><code>org.apache.tomcat.websocket.SSL_TRUSTSTORE</code></li>
     <li><code>org.apache.tomcat.websocket.SSL_TRUSTSTORE_PWD</code></li>
   </ul>
   <p>The default truststore password is <code>changeit</code>.</p>

<p>If the <code>org.apache.tomcat.websocket.SSL_CONTEXT</code> property is
   set then the <code>org.apache.tomcat.websocket.SSL_TRUSTSTORE</code> and
   <code>org.apache.tomcat.websocket.SSL_TRUSTSTORE_PWD</code> properties
   will be ignored.</p>

<p>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 <code>SSLContext</code> via the
   <code>org.apache.tomcat.websocket.SSL_CONTEXT</code> user property. The
   custom <code>SSLContext</code> must be configured with a custom
   <code>TrustManager</code> that extends
   <code>javax.net.ssl.X509ExtendedTrustManager</code>. The desired verification
   (or lack of verification) can then be controlled by appropriate
   implementations of the individual abstract methods.</p>

<p>When using the WebSocket client to connect to server endpoints, the number of
   HTTP redirects that the client will follow is controlled by the
   <code>userProperties</code> of the provided
   <code>javax.websocket.ClientEndpointConfig</code>. 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.
   </p>

<p>When using the WebSocket client to connect to a server endpoint that requires
   BASIC or DIGEST authentication, the following user properties must be set:
   </p>
   <ul>
     <li><code>org.apache.tomcat.websocket.WS_AUTHENTICATION_USER_NAME</code>
     </li>
     <li><code>org.apache.tomcat.websocket.WS_AUTHENTICATION_PASSWORD</code>
     </li>
   </ul>
   <p>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:</p>
   <ul>
     <li><code>org.apache.tomcat.websocket.WS_AUTHENTICATION_REALM</code></li>
   </ul>

<p>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:
   </p>
   <ul>
     <li><code>org.apache.tomcat.websocket.WS_PROXY_AUTHENTICATION_USER_NAME
     </code></li>
     <li><code>org.apache.tomcat.websocket.WS_PROXY_AUTHENTICATION_PASSWORD
     </code></li>
   </ul>
   <p>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:</p>
   <ul>
     <li><code>org.apache.tomcat.websocket.WS_PROXY_AUTHENTICATION_REALM</code>
     </li>
   </ul>

</section>

</body>
</document>
