简体   繁体   English

如何配置Apache以正确转发Websocket?

[英]How can I configure Apache to correctly forward websockets?

I have already looked at this question and various others on both SO and related sites, but none of the solutions suggested so far have worked. 我已经在SO和相关站点上研究了这个问题以及其他问题 ,但是到目前为止,所提出的解决方案均无效。

I am running tty.js on localhost:8080 and verified that websockets work correctly when hitting that port directly. 我在localhost:8080上运行tty.js并验证了直接访问该端口时websockets可以正常工作。 Now, I am attempting to connect to tty.js through an Apache reverse proxy. 现在,我正在尝试通过Apache反向代理连接到tty.js The application can work without using Websockets, but I am trying to understand why Websockets do not work. 该应用程序可以在不使用Websockets的情况下工作,但是我试图理解为什么Websockets无法工作。

Here is my Apache configuration for testing on localhost with a fresh Apache build from source . 这是我的Apache配置,用于使用来自的全新Apache构建在localhost上进行测试。

Listen 9000
# Load proxy modules
LoadModule proxy_module "modules/mod_proxy.so"
LoadModule proxy_http_module "modules/mod_proxy_http.so"
LoadModule proxy_wstunnel_module "modules/mod_proxy_wstunnel.so"

<VirtualHost *:9000>
ServerName localhost

ProxyPass /tty/socket.io/1/ ws://localhost:8080/socket.io/1/
ProxyPassReverse /tty/socket.io/1/ ws://localhost:8080/socket.io/1/
ProxyPass /tty/ http://localhost:8080/
ProxyPassReverse /tty/ http://localhost:8080/

</VirtualHost>

When I connect to http://localhost:9000/tty/ , I get a 500 error. 当我连接到http://localhost:9000/tty/ ,出现500错误。

In the server side logs, I get the following error. 在服务器端日志中,出现以下错误。

[Mon Jan 02 19:30:32.342551 2017] [proxy:warn] [pid 28226:tid 140098955872000] [client 127.0.0.1:38372] AH01144: No protocol handler was valid for the URL /tty/socket.io/1/. If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule., referer: http://localhost:9000/tty/

What is the correct configuration for Apache to make Websockets work correctly? Apache使Websockets正常工作的正确配置是什么?

After several hours of running Apache in a debugger, I discovered that Apache was faithfully passing all the requests that matched the given path through mod_proxy, including the following one. 在调试器中运行Apache几个小时后,我发现Apache正通过mod_proxy传递与给定路径匹配的所有请求,包括以下请求。

http://localhost:9000/tty/socket.io/1/

It turns out that this request goes out before the actual request with the Upgrade: Websocket header, and it is a normal AJAX request . 事实证明,此请求在带有Upgrade: Websocket标头的实际请求之前发出,并且它是正常的AJAX请求

When this request gets passed to mod_proxy_wstunnel , the module notices that the Websocket header is missing and declines to handle it, causing Apache to claim that No protocol handler was valid in the log message and return status code 500. 当此请求传递到mod_proxy_wstunnel ,模块会注意到Websocket标头丢失并拒绝对其进行处理,从而导致Apache声称日志消息中No protocol handler was valid ,并返回状态代码500。

The fix is to extend the path of the ProxyPath directive so that it only covers actual Websocket requests, and not stray Ajax requests. 解决方法是扩展ProxyPath指令的路径,以使其仅涵盖实际的Websocket请求,而不涉及杂散的Ajax请求。

ProxyPass /tty/socket.io/1/websocket/ ws://localhost:8080/socket.io/1/websocket/
ProxyPassReverse /tty/socket.io/1/websocket/ ws://localhost:8080/socket.io/1/websocket/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM