![](/img/trans.png)
[英]Error during WebSocket handshake: 'Upgrade' header is missing (Apache 2.4 + mod_proxy_wstunnel)
[英]WebSockets and Apache proxy : how to configure mod_proxy_wstunnel?
我有 :
Apache
(v2.4) 在我的服务器的端口 80 上为www.domain1.com
启用mod_proxy和mod_proxy_wstunnel
同一服务器的 3001 端口上的node.js + socket.io
。
访问www.domain2.com
(使用端口 80)重定向到 2. 感谢这里描述的方法。 我已经在 Apache 配置中设置了这个:
<VirtualHost *:80>
ServerName www.domain2.com
ProxyPass / http://localhost:3001/
ProxyPassReverse / http://localhost:3001/
ProxyPass / ws://localhost:3001/
ProxyPassReverse / ws://localhost:3001/
</VirtualHost>
它适用于所有内容,除了 websocket 部分: ws://...
不会像代理那样传输。
当我访问www.domain2.com
上的页面时,我有:
Impossible to connect ws://www.domain2.com/socket.io/?EIO=3&transport=websocket&sid=n30rqg9AEqZIk5c9AABN.
问题:如何让 Apache 也代理 WebSockets?
由于这个话题 ,我终于设法做到了。
去做:
1)安装Apache 2.4(不适用于2.2),并执行:
a2enmod proxy
a2enmod proxy_http
a2enmod proxy_wstunnel
2)让nodejs
在端口3001上运行
3)在Apache配置中执行此操作
<VirtualHost *:80>
ServerName www.domain2.com
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/socket.io [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) ws://localhost:3001/$1 [P,L]
ProxyPass / http://localhost:3001/
ProxyPassReverse / http://localhost:3001/
</VirtualHost>
注意:如果在使用websockets的同一服务器上有多个服务,则可能需要执行此操作以将它们分开。
您也可以按HTTP标头过滤,而不是按URL过滤。 此配置适用于任何使用websockets的Web应用程序,如果它们不使用socket.io:
<VirtualHost *:80>
ServerName www.domain2.com
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://localhost:3001/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule /(.*) http://localhost:3001/$1 [P,L]
ProxyPassReverse / http://localhost:3001/
</VirtualHost>
可能会有用。 只是所有查询都通过ws发送到节点
<VirtualHost *:80>
ServerName www.domain2.com
<Location "/">
ProxyPass "ws://localhost:3001/"
</Location>
</VirtualHost>
从Socket.IO 1.0(2014年5月)开始,所有连接都以HTTP轮询请求开始( 此处有更多信息)。 这意味着除了转发WebSocket流量之外,您还需要转发任何transport=polling
HTTP请求。
下面的解决方案应该正确地重定向所有套接字流量,而不重定向任何其他流量。
启用以下Apache2 mods:
sudo a2enmod proxy rewrite proxy_http proxy_wstunnel
在* .conf文件中使用这些设置(例如/etc/apache2/sites-available/mysite.com.conf
)。 我已经包含了解释每件作品的评论:
<VirtualHost *:80> ServerName www.mydomain.com # Enable the rewrite engine # Requires: sudo a2enmod proxy rewrite proxy_http proxy_wstunnel # In the rules/conds, [NC] means case-insensitve, [P] means proxy RewriteEngine On # socket.io 1.0+ starts all connections with an HTTP polling request RewriteCond %{QUERY_STRING} transport=polling [NC] RewriteRule /(.*) http://localhost:3001/$1 [P] # When socket.io wants to initiate a WebSocket connection, it sends an # "upgrade: websocket" request that should be transferred to ws:// RewriteCond %{HTTP:Upgrade} websocket [NC] RewriteRule /(.*) ws://localhost:3001/$1 [P] # OPTIONAL: Route all HTTP traffic at /node to port 3001 ProxyRequests Off ProxyPass /node http://localhost:3001 ProxyPassReverse /node http://localhost:3001 </VirtualHost>
我已经为路由/node
流量添加了一个额外的部分,我觉得很方便,请参阅此处了解更多信息。
在这些答案的帮助下,我终于使用这个Apache2站点配置在使用Ubuntu Mate和Apache2的Raspberry Pi上运行Node-RED的反向代理:
<VirtualHost *:80>
ServerName nodered.domain.com
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://localhost:1880/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule /(.*) http://localhost:1880/$1 [P,L]
</VirtualHost>
我还必须启用这样的模块:
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_wstunnel
对我来说,它只能在httpd.conf中添加一行 ,如下所示(粗线)。
<VirtualHost *:80>
ServerName: xxxxx
#ProxyPassReverse is not needed
ProxyPass /log4j ws://localhost:4711/logs
<VirtualHost *:80>
在CentOS上,Apache版本是2.4.6。
我的设置:
/api/ws
WebSockets 如上所述@Basj,请确保启用了a2enmod代理和ws_tunnel。
这是解决我的问题的Apache配置文件的屏幕截图:
相关部分为文字:
<VirtualHost *:80>
ServerName *******
ServerAlias *******
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
<Location "/api/ws">
ProxyPass "ws://localhost:3000/api/ws"
</Location>
</VirtualHost>
希望有所帮助。
对弹簧应用程序执行以下操作是否运行静态,休息和websocket内容。
Apache用作以下URI的代理和SSL端点:
<VirtualHost *:80>
ServerName xxx.xxx.xxx
ProxyRequests Off
ProxyVia Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
RewriteEngine On
# websocket
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule ^/api/ws/(.*) ws://localhost:8080/api/ws/$1 [P,L]
# rest
ProxyPass /api http://localhost:8080/api
ProxyPassReverse /api http://localhost:8080/api
# static content
ProxyPass /app http://localhost:8080/app
ProxyPassReverse /app http://localhost:8080/app
</VirtualHost>
我使用相同的vHost配置进行SSL配置,无需更改任何与代理相关的内容。
server.use-forward-headers: true
除了主要答案:如果在使用websockets的同一服务器上有多个服务,您可能希望通过使用自定义路径 (*)将它们分开:
节点服务器:
var io = require('socket.io')({ path: '/ws_website1'}).listen(server);
客户端HTML:
<script src="/ws_website1/socket.io.js"></script>
...
<script>
var socket = io('', { path: '/ws_website1' });
...
Apache配置:
RewriteEngine On
RewriteRule ^/website1(.*)$ http://localhost:3001$1 [P,L]
RewriteCond %{REQUEST_URI} ^/ws_website1 [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule ^(.*)$ ws://localhost:3001$1 [P,L]
RewriteCond %{REQUEST_URI} ^/ws_website1 [NC]
RewriteRule ^(.*)$ http://localhost:3001$1 [P,L]
(*)注意:使用默认的RewriteCond %{REQUEST_URI} ^/socket.io
不会特定于网站,并且websockets请求将在不同的网站之间混淆!
用于“投票”运输。
Apache方面:
<VirtualHost *:80>
ServerName mysite.com
DocumentRoot /my/path
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /my-connect-3001 http://127.0.0.1:3001/socket.io
ProxyPassReverse /my-connect-3001 http://127.0.0.1:3001/socket.io
</VirtualHost>
客户端:
var my_socket = new io.Manager(null, {
host: 'mysite.com',
path: '/my-connect-3001'
transports: ['polling'],
}).socket('/');
使用此链接获取ws https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html的 perfact解决方案
你必须在下面做一步..
转到/etc/apache2/mods-available
步骤1
使用以下命令启用mode proxy_wstunnel.load
$a2enmod proxy_wstunnel.load
第2步
转到/etc/apache2/sites-available
并在虚拟主机内的.conf文件中添加以下行
ProxyPass "/ws2/" "ws://localhost:8080/"
ProxyPass "/wss2/" "wss://localhost:8080/"
注意:8080意味着你的tomcat运行端口是因为我们要连接ws
,我们的war文件放在tomcat中,而tomcat为ws
提供apache。 谢谢
我的配置
ws://localhost/ws2/ALLCAD-Unifiedcommunication-1.0/chatserver?userid=4 =Connected
去做:
安装Apache 2.4(不适用于2.2), a2enmod proxy
和a2enmod proxy_wstunnel.load
在Apache配置中执行此操作
只需在文件中添加两行,其中8080是您的tomcat运行端口
<VirtualHost *:80> ProxyPass "/ws2/" "ws://localhost:8080/" ProxyPass "/wss2/" "wss://localhost:8080/" </VirtualHost *:80>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.