WebSocketハウツー

目次

概要

Tomcatは、RFC 6455で定義されているWebSocketのサポートを提供します。

アプリケーション開発

Tomcatは、Jakarta WebSocketプロジェクトで定義されているJakarta WebSocket 2.1 APIを実装しています。

WebSocket APIの使用方法を示すサンプルアプリケーションがいくつかあります。クライアント側のHTMLと、サーバー側のコードの両方を確認する必要があります。

Tomcat WebSocket固有の設定

Tomcatは、WebSocket用のTomcat固有の設定オプションをいくつか提供しています。これらは、時間の経過とともにWebSocket仕様に吸収されることが予想されます。

ブロッキングモードでWebSocketメッセージを送信する際に使用される書き込みタイムアウトは、デフォルトで20000ミリ秒(20秒)です。これは、WebSocketセッションにアタッチされたユーザープロパティコレクションでorg.apache.tomcat.websocket.BLOCKING_SEND_TIMEOUTプロパティを設定することで変更できます。このプロパティに割り当てる値はLongである必要があり、使用するタイムアウトをミリ秒単位で表します。無限のタイムアウトの場合は、-1を使用します。

セッションクローズタイムアウトは、デフォルトで30000ミリ秒(30秒)です。これは、WebSocketセッションにアタッチされたユーザープロパティコレクションでorg.apache.tomcat.websocket.SESSION_CLOSE_TIMEOUTプロパティを設定することで変更できます。このプロパティに割り当てる値はLongである必要があり、使用するタイムアウトをミリ秒単位で表します。0以下の値は無視されます。

Jakarta WebSocket APIの一部であるSession.setMaxIdleTimeout(long)メソッドに加えて、Tomcatはアクティビティがないためにセッションをタイムアウトさせるタイミングをより細かく制御できます。WebSocketセッションにアタッチされたユーザープロパティコレクションでorg.apache.tomcat.websocket.READ_IDLE_TIMEOUT_MSプロパティを設定すると、指定されたミリ秒数の間WebSocketメッセージを受信しない場合、セッションタイムアウトがトリガーされます。org.apache.tomcat.websocket.WRITE_IDLE_TIMEOUT_MSプロパティを設定すると、指定されたミリ秒数の間WebSocketメッセージを送信しない場合、セッションタイムアウトがトリガーされます。これらは、Session.setMaxIdleTimeout(long)の有無にかかわらず、個別に使用することも、組み合わせて使用することもできます。関連するプロパティが指定されていない場合、読み取りおよび/または書き込みアイドルタイムアウトが適用されます。

アプリケーションが受信バイナリメッセージに対してMessageHandler.Partialを定義しない場合、受信したバイナリメッセージはすべてバッファリングする必要があり、バイナリメッセージの登録済みMessageHandler.Wholeへの単一の呼び出しでメッセージ全体を配信できます。バイナリメッセージのデフォルトのバッファサイズは8192バイトです。これは、サーブレットコンテキスト初期化パラメーターorg.apache.tomcat.websocket.binaryBufferSizeを目的のバイト数に設定することで、Webアプリケーションに対して変更できます。

アプリケーションが受信テキストメッセージに対してMessageHandler.Partialを定義しない場合、受信したテキストメッセージはすべてバッファリングする必要があり、テキストメッセージの登録済みMessageHandler.Wholeへの単一の呼び出しでメッセージ全体を配信できます。テキストメッセージのデフォルトのバッファサイズは8192バイトです。これは、サーブレットコンテキスト初期化パラメーターorg.apache.tomcat.websocket.textBufferSizeを目的のバイト数に設定することで、Webアプリケーションに対して変更できます。

WebSocketクライアントを使用してサーバーエンドポイントに接続する場合、接続を確立する際のIO操作のタイムアウトは、提供されたjakarta.websocket.ClientEndpointConfiguserPropertiesによって制御されます。プロパティはorg.apache.tomcat.websocket.IO_TIMEOUT_MSであり、ミリ秒単位のStringとしてのタイムアウトです。デフォルトは5000(5秒)です。

WebSocketクライアントを使用してセキュアなサーバーエンドポイントに接続する場合、クライアントSSL構成はjakarta.websocket.ClientEndpointConfig.getSSLContext()を介して構成する必要があります。Tomcat 10.1.xは、TLS構成が提供されたjakarta.websocket.ClientEndpointConfiguserPropertiesを介して行われていた、WebSocket 2.1以前の構成方法もサポートしています。ただし、このアプローチは非推奨であり、Tomcat 11で削除される予定です。次のユーザープロパティがサポートされています。

  • 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

デフォルトのトラストストアパスワードはchangeitです。

org.apache.tomcat.websocket.SSL_CONTEXTプロパティが設定されている場合、org.apache.tomcat.websocket.SSL_TRUSTSTOREおよびorg.apache.tomcat.websocket.SSL_TRUSTSTORE_PWDプロパティは無視されます。

セキュアなサーバーエンドポイントの場合、ホスト名検証はデフォルトで有効になっています。この検証をバイパスするには(推奨されません)、org.apache.tomcat.websocket.SSL_CONTEXTユーザープロパティを介してカスタムSSLContextを提供する必要があります。カスタムSSLContextは、javax.net.ssl.X509ExtendedTrustManagerを拡張するカスタムTrustManagerで構成する必要があります。目的の検証(または検証の欠如)は、個々のアブストラクトメソッドの適切な実装によって制御できます。

WebSocketクライアントを使用してサーバーエンドポイントに接続する場合、クライアントが従うHTTPリダイレクトの数は、提供されたjakarta.websocket.ClientEndpointConfiguserPropertiesによって制御されます。プロパティはorg.apache.tomcat.websocket.MAX_REDIRECTIONSです。デフォルト値は20です。リダイレクトのサポートは、値をゼロに設定することで無効にできます。

WebSocketクライアントを使用して、BASICまたはDIGEST認証を必要とするサーバーエンドポイントに接続する場合、次のユーザープロパティを設定する必要があります。

  • org.apache.tomcat.websocket.WS_AUTHENTICATION_USER_NAME
  • org.apache.tomcat.websocket.WS_AUTHENTICATION_PASSWORD

オプションで、WebSocketクライアントは、サーバーの認証チャレンジに特定のレルムが含まれている場合にのみ資格情報を送信するように構成できます。そのレルムはオプションのユーザープロパティで定義します。

  • org.apache.tomcat.websocket.WS_AUTHENTICATION_REALM

WebSocketクライアントを使用して、BASICまたはDIGEST認証を必要とするフォワードプロキシ(ゲートウェイとも呼ばれます)を介してサーバーエンドポイントに接続する場合、次のユーザープロパティを設定する必要があります。

  • org.apache.tomcat.websocket.WS_PROXY_AUTHENTICATION_USER_NAME
  • org.apache.tomcat.websocket.WS_PROXY_AUTHENTICATION_PASSWORD

オプションで、WebSocketクライアントは、サーバーの認証チャレンジに特定のレルムが含まれている場合にのみ資格情報を送信するように構成できます。そのレルムはオプションのユーザープロパティで定義します。

  • org.apache.tomcat.websocket.WS_PROXY_AUTHENTICATION_REALM