[socket.io Apache2的https代理配置

问题描述 投票:0回答:1

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

socket = io.connect('');

服务器脚本位于https://github.com/miguelgrinberg/python-socketio/blob/master/examples/server/wsgi/app.py-我正在端口5000上运行服务器。

您可能需要了解的有关客户端和服务器的所有信息是,它们在我的localhost 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

现在我们有了一个网络套接字,其余的通信正在通过它进行。

我现在想尝试的两天是让示例在我的Web服务器上运行-因此,我正在寻找一个有效的apap 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特殊字符也出现在正常的localhost通信中-因此它们似乎属于那里)。

我在做什么错?

更新-接近解决方案!

[我尝试了socket.io示例服务器的多个Python和NodeJS实现以及几个客户端脚本-它们都创建了相同的问题,这证实了我的观点,Apache是​​问题所在。

我安装了Nginx并找到了最终可用的配置!这些是魔术线:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

我现在正在使用调试服务器,该服务器打印所有收到的HTTP请求,以将Nginx请求与Apache2请求进行比较,目的是配置Apache2以传递与Nginx相同的标头。

最后一个挑战似乎是将Nginx配置行转换为Apache2。听起来比它要容易..但这将是解决方案的关键。

socket.io apache2 reverse-proxy mod-proxy mod-proxy-wstunnel
1个回答
0
投票

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

我将此代码放入我的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 Server在调试HTTP标头方面给了我很多帮助:https://riptutorial.com/node-js/example/22405/a-simple-tcp-server

© www.soinside.com 2019 - 2024. All rights reserved.