如何通过 Apache 将 WebSocket 代理到 Play-Framework
How to proxy WebSocket via Apache to Play-Framework
我受困于我的 Apache 配置,感谢任何帮助。
配置是这样的:
- Apache 将所有 http 流量重定向到 https
- 它代理像 https://domain.tld/app1 to http://domain.tld:9000/app1 这样的请求(Play 应用程序 运行 在 app-context /app*/...)
这适用于以下 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。
我受困于我的 Apache 配置,感谢任何帮助。
配置是这样的:
- Apache 将所有 http 流量重定向到 https
- 它代理像 https://domain.tld/app1 to http://domain.tld:9000/app1 这样的请求(Play 应用程序 运行 在 app-context /app*/...)
这适用于以下 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。