如何通过 Apache 将 WebSocket 代理到 Play-Framework

How to proxy WebSocket via Apache to Play-Framework

我受困于我的 Apache 配置,感谢任何帮助。

配置是这样的:

这适用于以下 Apache 配置:

<VirtualHost *:80>
    ServerName domain.tld
    DocumentRoot /var/www/html
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
    Redirect permanent / https://domain.tld/
    Redirect permanent / https://domain.tld/
</VirtualHost>

<VirtualHost _default_:443>
#ssl-config here
<Proxy http://localhost:9000/*>
      Order deny,allow
      Allow from all
</Proxy>
ProxyPass         /app1  http://domain.tld:9000/app1
ProxyPassReverse  /app1  http://domain.tld:9000/app1
ProxyPassReverse  /app1  http://domain.tld/app1
</VirtualHost>

问题是,一个播放应用程序添加了 WebSocket。这不适用于上述设置。所以我阅读了 play-pages 上的内容。这让我安装了 mod_proxy_wstunnel。我还将以下行添加到配置中,但没有成功:

ProxyPass         /app1/timerWs ws://domain.tld:9000/app1/timerWs
ProxyPassReverse  /app1/timerWs ws://domain.tld:9000/app1/timerWs

当我尝试连接到 https://domain.tld/rlc/timerWs 时,我收到了 500 内部服务器错误,但是 apache 错误日志中没有新的、更具体的错误。

如何配置 Apache 以将 WebSocket 请求正确地代理到我的游戏应用程序?

我的播放应用程序没有 https 适配器。所有 https 的东西都是由 Apache-proxy 完成的。

Play-apps 的版本是 2.5。 Apache 在 2.4.7.

非常感谢您的帮助。 托拜厄斯

我现在已经解决了这个问题。诀窍是不仅在 Apache 上,而且在 Plays 应用程序服务器 Jetty 上设置 https。为此,请参阅 link。这导致另一个 ProxyPass 地址(注意 wss 而不是 ws):

ProxyPass         /app1/timerWs wss://domain.tld:9000/app1/timerWs
ProxyPassReverse  /app1/timerWs wss://domain.tld:9000/app1/timerWs

我还必须更改 Javascript 中的 WebSocket 地址,让浏览器知道在哪里可以找到 WebSocket 后端。

$(function() {
    var WS = window['MozWebSocket'] ? MozWebSocket : WebSocket
    var dateSocket = new WS("wss://domain.tld/rlc/timerWs")
    var receiveEvent = function(event) {
        $("#timer").html(event.data);
    }
    dateSocket.onmessage = receiveEvent
});

在此之前,我使用了 Play-route @routes.Application.timerWs().webSocketURL(request) 来寻址 WebSocket。