54

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

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

  • 除了浏览器兼容性之外,我应该注意问题 1 中描述的方法的任何缺点吗?

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

  • 除了 JavaScript 之外,我可以使用任何语言连接到我的网络套接字吗?

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

4

3 回答 3

38

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

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

于 2014-06-04T15:58:45.803 回答
31

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

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

现在使用 Apache HTTP Server 可能是可行的,并且我已经看到了一些示例,但是没有官方支持并且它变得复杂。阿帕奇会做什么?你的处理程序在哪里?有一个模块可以将传入的 WS 请求转发到外部共享库,但这对于使用 WS 的其他出色工具来说不是必需的。

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

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

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

关于协议,正如Wikipedia 所示,它看起来像这样:

客户端发送:

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

将回复错误或页面内容。

于 2013-06-27T15:29:49.673 回答
11

我很难理解https 的 websockets的代理设置,因此让我在这里澄清一下我所意识到的。

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

<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>

在您的前端应用程序中使用 url"wss://example.com/wss/"这非常重要,如果您被 websockets 卡住,您可能会在前端 url 中出错。您可能会像下面这样错误地输入 url。

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

另一个有趣的部分是,如果你在前端写,最后一个与value/wss/相同,你应该写在 url 的末尾。proxypassproxypass /ws//ws/

于 2018-08-09T15:08:33.590 回答