配置Apache2代理WebSocket?


40

WebSocket协议是HTTP协议的扩展。但是,Apache2的代理模块似乎对此一无所知,并丢弃了重要的标头,从而将调用转换为标准的HTTP调用。

有没有一种方法可以使Apache2(1)理解WebSocket或(2)盲目地传递其获得的一切?

Answers:


23

Apache中继中现在有一个名为mod_proxy_wstunnel的模块,该模块允许mod_proxy(ProxyPass / ProxyPassReverse)通过WebSocket通信。有人写了一篇博客文章,关于将mod_proxy_wstunnel反向移植到Apache 2.4 / 2.2,并提供了一个补丁。

我想出了在Ubuntu上设置mod_proxy_wstunnel的具体说明(已通过Ubuntu Server 11.10和Apache 2.2.20测试),并将其发布在我的博客上。我在下面复制了它们:

# Check apache version (should be 2.2.20 as of writing, if not adjust the next step)
dpkg -s apache2

# Checkout apache source
svn checkout http://svn.apache.org/repos/asf/httpd/httpd/tags/2.2.20/ httpd-2.2.20

# Get patch and apply it
wget http://cafarelli.fr/gentoo/apache-2.2.24-wstunnel.patch
cd httpd-2.2.20
patch -p1 < ../apache-2.2.24-wstunnel.patch

# Build Apache 
svn co http://svn.apache.org/repos/asf/apr/apr/branches/1.4.x srclib/apr
svn co http://svn.apache.org/repos/asf/apr/apr-util/branches/1.3.x srclib/apr-util
./buildconf
./configure --enable-proxy=shared --enable-proxy_wstunnel=shared
make

# Copy the module and recompiled mod_proxy (for new symbols) to the ubuntu apache installation and update the permissions to match the other modules
sudo cp modules/proxy/.libs/mod_proxy{_wstunnel,}.so /usr/lib/apache2/modules/
sudo chmod 644 /usr/lib/apache2/modules/mod_proxy{_wstunnel,}.so
echo -e "# Depends: proxy\nLoadModule proxy_wstunnel_module /usr/lib/apache2/modules/mod_proxy_wstunnel.so" | sudo tee -a /etc/apache2/mods-available/proxy_wstunnel.load

# Enable the module (also make any configuration changes you need)
sudo a2enmod proxy_wstunnel
sudo service apache2 restart

2
当我按照您的指南进行操作时,您没有采取任何步骤。完成apr结帐后,我必须运行./buildconfig以创建配置文件。它告诉我要安装一些依赖项。
notbad.jpeg 2013年

将它与Glassfish 4通过wss挂钩:(SSL)
Archimedes Trajano 2014年

1
@ notbad.jpeg:您可能是说./buildconf(不是./buildconfig):-)
Erik Forsberg

1
只是我的反馈...这是从Ubuntu 12.04安装和加载到Apache 2.2.22-1ubuntu1.10中的,但最终对我没有用。代理删除了“ Upgrade”标头(源代码显示“ RFC2616 13.5.1说我们应该剥离这些标头”),这是服务器期望的标头,而不仅仅是一跳,因此它对我不起作用,我已经用iptables DNAT规则代替了它。
彼得




1

这个关于@Andrew Moss的答案是关于如何正确配置VirtualHost使其与socket.io 1.0一起使用的!随意跳过有关CentOS的部分!


如果您坚持使用CentOS 6,请按以下步骤操作:

  1. 此处下载mod_proxy_wstunnel模块的反向移植源(克隆Gist或单独下载文件)
  2. 安装构建所需的一切: yum install make gcc httpd-devel
  3. 设置一个RPM Build环境(基本上是一个没有特权的用户和一些目录)
  4. .c-file 复制到SOURCES环境的子文件夹中,并将-file 复制到子.spec文件SPECS夹中。
  5. rpmbuild -ba mod_proxy_wstunnel.spec
  6. 该软件包现在位于SRPMS子文件夹中
  7. 安装软件包: rpm -i /path/to/package.rpm
  8. 利润

这还将自动将模块加载到Apache中,因此您只需使用重启即可service httpd restart


在Apache 2.2上,设置一个模块VirtualHost来实际服务Socket.io服务器和客户端脚本(默认情况下,该脚本可在上获得http://your.server/socket.io/socket.io.js),这是由于模块中的Bugmod_proxy所致:

给定以下重写规则:

RewriteRule    ^/ws(.*)$  ws://localhost:9000/ws  [P]

mod_rewrite 将其视为文件路径,以便访问日志显示:

[26/Sep/2013:09:46:07 -0400] "GET /ws://localhost:9000/ws HTTP/1.1" 400 317

因此,您不能ws在rewrite-rule中使用-protocol,因为它将在内部转换为HTTP GET请求。

但是有一种解决方法:

<VirtualHost *:80>
        ServerName your.server

        # Proxy socket.io Websocket
        RewriteEngine On

        # socket.io 1.0+ starts all connections with an HTTP polling request
        RewriteCond %{QUERY_STRING} transport=polling       [NC]
        RewriteRule /(.*)           http://localhost:8081/$1 [P]

        ProxyRequests Off

        # Explicitly send the request for the client-script to HTTP:
        ProxyPass /socket.io/socket.io.js http://localhost:8081/socket.io/socket.io.js
        ProxyPassReverse /socket.io/socket.io.js http://localhost:8081/socket.io/socket.io.js

        # Anything else goes to the WebSocket protocol:
        ProxyPass /socket.io/ ws://localhost:8081/socket.io/
        ProxyPassReverse /socket.io/ ws://localhost:8081/socket.io/

        # Any additional stuff (the actual site) comes here
        ProxyPass / http://localhost:8081/
        ProxyPassReverse / http://localhost:8081/
</VirtualHost>

这可以确保一切发送到/socket.io转到ws://-protocol,除了长轮询请求(这是当WebSockets的不可回退机制)和客户端库的要求。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.