apache2的socket.io https代理配置

apache2的socket.io https代理配置,socket.io,apache2,reverse-proxy,mod-proxy,mod-proxy-wstunnel,Socket.io,Apache2,Reverse Proxy,Mod Proxy,Mod Proxy Wstunnel,我有一个工作socket.io设置,带有一个JavaScript客户端和一个python服务器。 客户机基本上只是一行: WebSocket握手期间出错:意外响应代码:404 socket = io.connect(''); 服务器脚本可以在以下位置找到-我正在端口5000上运行服务器 关于客户机和服务器,您可能需要知道的是,它们在我的本地主机apache安装上工作得非常好,socket.io从GET请求开始,然后从那里升级到websocket。成功的握手是这样的: http://localh

我有一个工作socket.io设置,带有一个JavaScript客户端和一个python服务器。 客户机基本上只是一行: WebSocket握手期间出错:意外响应代码:404

socket = io.connect('');
服务器脚本可以在以下位置找到-我正在端口5000上运行服务器

关于客户机和服务器,您可能需要知道的是,它们在我的本地主机apache安装上工作得非常好,socket.io从GET请求开始,然后从那里升级到websocket。成功的握手是这样的:

http://localhost:5000/socket.io/?EIO=3&transport=polling&t=N1kLfSx
http://localhost:5000/socket.io/?EIO=3&transport=polling&t=N1kLfTI&sid=70ddae8b36da4f0f8f9a851fa2c0121e
ws://localhost:5000/socket.io/?EIO=3&transport=websocket&sid=70ddae8b36da4f0f8f9a851fa2c0121e
现在我们有了一个websocket,其余的通信都是通过它运行的

我花了两天的时间试图让这个示例在我的web服务器上运行——因此我正在寻找一个可以工作的apache https配置,它可以将请求代理到端口5000上的后端服务器

我尝试了几十种不同的配置,但没有一种有效——它们看起来都非常类似。URL重写部分用于在初始握手成功后代理websocket连接

RewriteEngine On
RewriteCond %{REQUEST_URI}  ^/socket.io            [NC]
RewriteCond %{QUERY_STRING} transport=websocket    [NC]
RewriteRule /(.*)           ws://localhost:5000/$1 [P,L]

ProxyPass        /socket.io/ http://localhost:5000/socket.io/
ProxyPassReverse /socket.io/ http://localhost:5000/socket.io/
Apache将第一个socket.io GET请求转发给服务器,服务器会回复:

    ÿ0{"sid":"2efa0dbbce4c4eef958e70b393639610","upgrades":["websocket"],"pingTimeout":60000,"pingInterval":25000}ÿ42["my_response",{"data":"Connected","count":0}]ÿ40
然后立即打开并再次关闭websocket(代码404)。然后,客户端发送一个POST请求,该请求失败(代码400)。然后客户端重新开始第1步:发出GET请求,获取新会话id

(工作的本地主机通信中也会出现
ÿXX
特殊字符,因此它们似乎属于本地主机通信)

我做错了什么

更新-接近解决方案

我尝试了socket.io示例服务器的几个Python和NodeJS实现,以及几个客户端脚本——所有这些脚本都产生了相同的问题,这证实了我的论点,即Apache就是问题所在

我安装了Nginx,并找到了一个最终有效的配置! 这些是神奇的线条:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
我现在使用的是一个调试服务器,它打印所有接收到的HTTP请求,将Nginx请求与Apache2请求进行比较,目的是将Apache2配置为传递与Nginx相同的头


最后一个挑战似乎是将Nginx配置行转换为Apache2。听起来比实际情况容易。。不过,这将是解决方案的关键。

最后!经过一周的研究,我终于找到了一个有效的解决方案:

我将此代码放入Apache2配置的部分:

        ProxyRequests off
        ProxyVia on
        RewriteEngine On

        RewriteEngine On
        RewriteCond %{HTTP:Connection} Upgrade [NC]
        RewriteCond %{HTTP:Upgrade} websocket [NC]
        RewriteRule /(.*) ws://127.0.0.1:8080/$1 [P,L]

        ProxyPass               / http://127.0.0.1:5000/
        ProxyPassReverse        / http://127.0.0.1:5000/
有一百万种配置,我都试过了——这是唯一对我有效的配置。问题是,Apache2没有转发“Upgrade=websocket”和“Connection=Upgrade”标题。给定的重写命令使Apache2将这些头添加到代理连接

在研究这一点时,我首先发现了一个工作的Nginx配置,然后将其转换为Apache2。因此,如果您在Nginx中遇到此问题,可以在此处使用:

        location / {
                proxy_pass http://127.0.0.1:5000/;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header Host $host;
                proxy_cache_bypass $http_upgrade;
        }
这个小小的NodeJS TCP服务器在调试HTTP标头方面帮了我很多忙:

FYI:我尝试了stackoverflow(和许多其他来源)上提出的每一种配置。我做了我自己的研究,并回顾了所有现有的答案。