在Apache上设置websocket?

时间:2013-06-27 04:03:10

标签: apache websocket

所以我正在做一些关于websockets的研究,我有一些问题似乎无法找到明确的答案:

  • 如何在Linux服务器上设置Web套接字?有Apache模块吗?我是否使用第三方PHP代码或类似代码?

  • 问题1中描述的方法有哪些缺点,除浏览器兼容性外,我应该注意哪些?

  • 如何将我的websocket安装“升级”为安全的websocket安装(ws:// to wss://)?如果已在我的Apache服务器上设置SSL,这会变得更容易还是更难?

  • 我是否可以使用任何语言连接到除JavaScript以外的网络套接字?

  • 网络套接字的默认请求方法是什么?

3 个答案:

答案 0 :(得分:28)

Apache HTTP Server的新版本2.4有一个名为mod_proxy_wstunnel的模块,它是一个websocket代理。

http://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html

答案 1 :(得分:23)

我无法回答所有问题,但我会尽力而为。

正如您所知,WS只是一个持久的全双工TCP连接,带有帧消息,其中初始握手类似于HTTP。您需要一些服务器正在侦听传入的WS请求并将处理程序绑定到它们。

现在有可能使用Apache HTTP Server,我已经看到了一些例子,但是没有官方的支持而且它变得复杂了。 Apache会做什么?你的经纪人在哪里?有一个模块可以将传入的WS请求转发到外部共享库,但是使用其他很棒的工具来处理WS并不是必需的。

WS服务器趋势现在包括:Autobahn(Python)和Socket.IO(Node.js =服务器上的JavaScript)。后者还支持其他hackish“持久”连接,如长轮询和所有COMET内容。还有其他鲜为人知的WS服务器框架,如Ratchet(PHP,如果你只是熟悉它)。

在任何情况下,您都需要侦听端口,当然该端口不能与您机器上已运行的Apache HTTP Server相同(默认值= 80)。你可以使用像8080这样的东西,但即使这个特定的一个是一个流行的选择,一些防火墙可能仍会阻止它,因为它不应该是Web流量。这就是为什么许多人选择443,这是 HTTP安全端口,由于显而易见的原因,防火墙不会阻止。如果您不使用SSL,则可以使用80表示HTTP,使用443表示WS。 WS服务器不需要是安全的;我们只是在使用这个端口。

编辑:根据Iharob Al Asimi的说法,前一段是错误的。我没有时间对此进行调查,所以请查看他的工作以获取更多详细信息。

关于协议,如Wikipedia shows,它看起来像这样:

客户发送:

GET /mychat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat
Sec-WebSocket-Version: 13
Origin: http://example.com

服务器回复:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

并保持连接活动。如果您可以实现此握手和基本消息框架(使用描述它的小标头封装每条消息),那么您可以使用您想要的任何客户端语言。 JavaScript仅用于Web浏览器,因为它是内置的。

正如您所看到的,默认的“请求方法”是一个初始的HTTP GET,虽然这不是HTTP,并且在握手之后会丢失与HTTP相关的所有内容。我猜服务器不支持

Upgrade: websocket
Connection: Upgrade

将回复错误或网页内容。

答案 2 :(得分:2)

我很难理解 websockets for https 的代理设置,因此在这里我要清楚说明一下。

首先,您需要启用StartUpproxy apache模块,并且apache配置文件如下所示。

proxy_wstunnel

在前端应用程序中使用URL <IfModule mod_ssl.c> <VirtualHost _default_:443> ServerName www.example.com ServerAdmin webmaster@localhost DocumentRoot /var/www/your_project_public_folder SSLEngine on SSLCertificateFile /etc/ssl/certs/path_to_your_ssl_certificate SSLCertificateKeyFile /etc/ssl/private/path_to_your_ssl_key <Directory /var/www/your_project_public_folder> Options Indexes FollowSymLinks AllowOverride All Require all granted php_flag display_errors On </Directory> ProxyRequests Off ProxyPass /wss/ ws://example.com:port_no ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> </IfModule> ,这一点非常重要,尤其是如果您卡在websocket中,则可能会在前端URL中出错。您可能像下面这样错误地输入了网址。

"wss://example.com/wss/"

另一个有趣的部分是,如果您编写wss://example.com:8080/wss/ -> port no should not be mentioned ws://example.com/wss/ -> url should start with wss only. wss://example.com/wss -> url should end with / -> most important ,则最后一个/wss/proxypass值相同,那么在前端,您应该在url末尾写入proxypass /ws/