我依赖的 websocket 库(PHP-Websockets) 尚不支持安全套接字 ( wss
)。https
但我的网站是通过此服务提供的,因此无法使用不安全的ws
连接。
我正在尝试使用阿帕奇的mod_proxy
将来自浏览器的安全请求转发到客户端。
JavaScript
var ws = new Websocket('wss://example.com/_ws_/');
Apache 虚拟主机
ProxyPass "/_ws_/" "ws://127.0.0.1:8080/"
ProxyPassReverse "/_ws_/" "ws://127.0.0.1:8080/"
# I've also tried "/_ws_/" "ws://example.com:8080/" Same error below
尝试连接时,浏览器会收到500 Server Error
。日志显示:
对于 URL /_ws_/,没有有效的协议处理程序。如果您使用的是 mod_proxy 的 DSO 版本,请确保使用 LoadModule 将代理子模块包含在配置中。
我已经确认,如果我删除代理规则,停止将用户重定向到https
并尝试从浏览器连接到不安全的套接字:new Websocket('ws://example.com/')
,一切都会正常工作。
我加载的 Apache 模块包括mod_ssl.c
和mod_proxy.c
mod_proxy_http.c
Apache 2.4
答案1
为了使它正常工作,我还需要加载mod_proxy_wstunnel
一旦我这样做了,这个规则集就可以让一切正常工作:(在VirtualHost
接收和代理 websocket 请求的域中)
<IfModule mod_proxy.c>
ProxyPass "/_ws_/" "ws://127.0.0.1:8080/"
ProxyPassReverse "/_ws_/" "ws://127.0.0.1:8080/"
</IfModule>
然后浏览器可以通过 HTTPS 端口联系后端 WS 服务器:
var ws = new Websocket('wss://example.com/_ws_/');
答案2
我的代表没有给予我足够的权限来赞同上面的评论,我真的很难找到最好的答案,所以我将分享一个完整的例子,也许它会对你们中的一些人有所帮助。
<VirtualHost *:80>
ServerName yourdomain.com
DocumentRoot THEPATHGOESHERE/public
DirectoryIndex index.php
<Directory THEPATHGOESHERE/>
AllowOverride All
Order Deny,Allow
Allow from all
</Directory>
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName yourdomain.com
DocumentRoot THEPATHGOESHERE/public
DirectoryIndex index.php
<Directory THEPATHGOESHERE/>
AllowOverride All
Order Deny,Allow
Allow from all
</Directory>
SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/yourdomain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
<IfModule mod_proxy.c>
ProxyPass "/connection/websocket" "ws://yourdomain.com:8088/connection/websocket"
ProxyPassReverse "/connection/websocket" "ws://yourdomain.com:8088/connection/websocket"
</IfModule>
</VirtualHost>
</IfModule>
答案3
我认为问题是你没有加载修改代理服务器模块。它是反向代理 WebSocket 连接所必需的。