本篇介紹如何使用 Tomcat 開發 WebSocket 伺服器,並設定 SSL 安全加密的 Apache Proxy 連線。

WebSocket 的伺服器可以使用各種程式語言來撰寫,在 Apache 與 Tomcat 的整合架構下,可以直接用 Java 撰寫一個 WebSocket 伺服器,放在 Tomcat 中直接運行,這樣就不需要另外安裝太多的東西,以下是完整的開發與架設流程。

基本架構

這裡我使用 Java 開發 WebSocket 伺服器,佈署在後端的 Tomcat 應用伺服器上,前端放置 Apache 網頁伺服器,透過 Proxy 的方式將 WebSocket 導向後端,全程都使用 SSL 加密的連線。

WebSocket 伺服器架構(LibreOffice 原始檔

在進行 WebSocket 伺服器的開發之前,要先架設好 Apache 與 Tomcat 的整合架構,並且完成網頁伺服器的 SSL 憑證設定,讓 Apache 與 Tomcat 都可以正常提供 HTTPS 安全加密的連線。

Java 實作 WebSocket 伺服器

依照 Apache 官方的 mod_proxy_wstunnel 模組說明文件,加入 WebSocket 的 Proxy 設定:

ProxyPass "/ws"  "ws://localhost:8080/ws"
ProxyPass "/wss"  "wss://localhost:8443/wss"

一般未加密的 WebSocket 應該這樣就可以使用了。

若是使用 Apache 的 nss 模組來處理加密的連線時,可能會遇到的問題是沒有啟用 SSL Proxy 功能,產生 500 的錯誤碼,在 Apache 的紀錄檔中出現這樣的錯誤訊息:

[Mon Apr 17 09:35:25.466218 2017] [:error] [pid 17747] SSL Proxy requested for host.nxhx.org.tw but not enabled [Hint: NSSProxyEngine]
[Mon Apr 17 09:35:25.466258 2017] [proxy:error] [pid 17747] AH00961: WSS: failed to enable ssl support for [::1]:8443 (localhost)

這個問題一直解決不了,後來直接把 mod_nss 停掉,改用 mod_ssl 模組,在處理 wss 加密的 WebSocket 之前,啟用 SSLProxyEngine

<VirtualHost _default_:443>
  # ...
  ProxyRequests Off
  SSLProxyEngine On
  <Location "/wss">
    ProxyPass wss://localhost:8443/wss
  </Location>
  # ...
</VirtualHost>

參考資料:StackOverflowApache mod_ssl 官方文件StackOverflowStackOverflowTomcat 官方文件