首先,了解如何建立 webSocket 连接很重要,因为这对 webSocket 连接和 Web 服务器之间的关系很重要。
每个 webSocket 连接都以 HTTP 请求开始。浏览器向请求 webSocket 连接的主机/端口发送 HTTP 请求。该请求可能如下所示:
GET /chat HTTP/1.1
Host: example.com:8000
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
此请求与对该服务器的任何其他 HTTP 请求的区别在于请求中的Upgrade: websocket
标头。这告诉 HTTP 服务器这个特定的请求实际上是一个发起 webSocket 连接的请求。此标头还允许 Web 服务器区分常规 HTTP 请求和打开 webSocket 连接的请求。这允许在架构中进行一些非常重要的事情,并且完全是故意这样做的。这允许使用完全相同的服务器和端口来为您的 Web 请求和 webSocket 连接提供服务。所需要的只是 Web 服务器上的一个组件,该组件在Upgrade
所有传入的 HTTP 连接上查找此标头,如果找到,它将接管连接并将其转换为 webSocket 连接。
一旦服务器识别到此upgrade
标头,它就会以合法的 HTTP 响应进行响应,但它会向客户端发出信号表明已接受对 webSocket 协议的升级,如下所示:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
此时,客户端和服务器都将原始 HTTP 请求中的套接字保持打开状态,并且都切换到 webSocket 协议。
现在,针对您的具体问题:
我的应用程序如何与 Web 服务器和/或 WebSockets 库通信以发送/接收数据?
您的应用程序可以使用现代浏览器中内置的 webSocket 支持,并且可以像这样启动 webSocket 连接:
var socket = new WebSocket("ws://www.example.com");
这将指示浏览器启动 webSocket 连接以www.example.com
使用与当前网页连接的相同端口。由于浏览器内置了 webSocket 支持,上述 HTTP 请求和升级协议是由客户端自动为您处理的。
在服务器端,您需要确保您使用的 Web 服务器具有传入的 webSocket 支持,并且支持已启用和配置。因为一个 webSocket 连接一旦建立起来就是一个持续的连接,它根本不遵循 CGI 模型。必须至少有一个长时间运行的进程来处理实时 webSocket 连接。在服务器模型(如 CGI)中,您需要某种 webServer 插件来支持您的 webSocket 连接的这种长时间运行的过程。在像 node.js 这样已经是一个长期运行的进程的服务器环境中,添加 webSockets 在架构上根本没有改变——而只是一个额外的库来支持 webSocket 协议。
我建议您可能会发现这篇文章很有趣,因为它讨论了从 CGI 风格的单一请求处理到 webSocket 的连续套接字连接的转变:
Web Evolution:从 CGI 到 Websockets(以及它将如何帮助您更好地监控您的云基础设施)
如果你真的想坚持使用标准输入/标准输出模型,有一些库可以为你的 webSockets 建模。这是一个这样的库。他们的标语是“这就像二十年后的 CGI,用于 WebSockets”。
我试图弄清楚如何向其中添加 WebSockets 支持。我更喜欢使用编译的解决方案,而不是解释的东西,如 JavaScript、Python 或 PHP。
抱歉,我不熟悉那个特定的服务器环境。可能需要进行一些深入的搜索才能找出您的选择。由于 webSocket 连接是连续连接,因此您将需要一个连续运行的进程,该进程可以是 webSocket 连接的服务器端部分。这可以是您的 webServer 中内置的东西,也可以是 webServer 启动并将传入连接转发到的附加进程。
仅供参考,我在家里有一个基于 Raspberry Pi 的自定义应用程序,它使用 webSockets 与浏览器网页进行实时通信,它工作得很好。我碰巧将 node.js 用于服务器环境和在 webSockets 之上运行的 socket.io 库,以便在 webSockets 之上为我提供更高级别的接口。我的服务器代码会定期检查几个硬件传感器,然后每当有新的/更改的数据要报告时,它就会向任何打开的 webSockets 发送消息,以便连接的浏览器获得传感器读数的实时更新。
您可能需要一些长时间运行的应用程序,将传入的 webSocket 连接从 web 服务器传递到长时间运行的进程,或者您需要在与 web 服务器不同的端口上建立 webSocket 连接(因此它们可以由完全不同的服务器进程)在这种情况下,您将拥有一个完全独立的服务器来处理您的 webSocket 请求和套接字(该服务器还必须支持 CORS 以使浏览器能够连接到它,因为它与您的网页不同的端口)。