WebSockets 服务器架构如何工作? [英] How does WebSockets server architecture work?

查看:31
本文介绍了WebSockets 服务器架构如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图更好地了解服务器端架构如何为 WebSockets 工作,目标是在嵌入式应用程序中实现它.似乎这里有 3 个不同的服务器端软件组件在起作用:1) 为静态 HTTP 页面提供服务并处理升级请求的 Web 服务器,2) 一个 WebSockets 库,例如 libwebsockets,用于处理 WebSockets 通信的具体细节", 和 3) 我的自定义应用程序来实际弄清楚如何处理传入的数据.所有这些如何组合在一起?拥有单独的 Web 服务器和 WebSocket 处理部分(也称为 WebSocket 服务器/守护程序)是否很常见?

I'm trying to get a better understanding of how the server-side architecture works for WebSockets with the goal of implementing it in an embedded application. It seems that there are 3 different server-side software components in play here: 1) the web server to serve static HTTP pages and handle upgrade request, 2) a WebSockets library such as libwebsockets to handle the "nuts and bolts" of WebSockets communications, and 3) my custom application to actually figure out what to do with incoming data. How do all these fit together? Is it common to have a separate web server and WebSocket handling piece, aka a WebSocket server/daemon?

我的应用程序如何与 Web 服务器和/或 WebSockets 库通信以发送/接收数据?例如,对于 CGI,Web 服务器使用环境变量向自定义应用程序发送信息,并使用 stdout 接收响应.这里等效的通信系统是什么?或者您通常将 WebSocket 库链接到客户应用程序中?但是,如何与 Web 服务器通信到 WebSocket 库 + 自定义应用程序?或者所有 3 个组合成一个组件?

How does my application communicate with the web server and/or WebSockets library to send/receive data? For example, with CGI, the web server uses environmental variables to send info to the custom application, and stdout to receive responses. What is the equivalent communication system here? Or do you typically link in a WebSocket library into the customer application? But then how would communication with the web server to the WebSocket library + custom application work? Or all 3 combined into a single component?

这就是我问的原因.我在内存有限的 Blackfin 处理器上的 uClinux/no MMU 平台上使用 boa Web 服务器.boa 中没有原生 WebSocket 支持,只有 CGI.我想弄清楚如何为此添加 WebSockets 支持.我更喜欢使用编译的解决方案,而不是解释性的解决方案,例如 JavaScript、Python 或 PHP.我当前的应用程序在 CGI 上使用长轮询,这不能为计划的增强提供足够的性能.

Here's why I am asking. I'm using the boa web server on a uClinux/no MMU platform on a Blackfin processor with limited memory. There is no native WebSocket support in boa, only CGI. I'm trying to figure out how I can add WebSockets support to that. I would prefer to use a compiled solution as opposed to something interpreted such as JavaScript, Python or PHP. My current application using long polling over CGI, which does not provide adequate performance for planned enhancements.

推荐答案

首先,了解 webSocket 连接是如何建立的很重要,因为这在 webSocket 连接和您的 Web 服务器之间起着重要的作用.

First off, it's important to understand how a webSocket connection is established because that plays into an important relationship between webSocket connections and your web server.

每个 webSocket 连接都以 HTTP 请求开始.浏览器向请求 webSocket 连接的主机/端口发送 HTTP 请求.该请求可能如下所示:

Every webSocket connection starts with an HTTP request. The browser sends an HTTP request to the host/port that the webSocket connection is requested on. That request might look something like this:

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 服务器上的一个组件,它会在所有传入的 HTTP 连接上查找此 Upgrade 标头,如果找到,它将接管连接并将其转换为 webSocket 连接.

What distinguishes this request from any other HTTP request to that server is the Upgrade: websocket header in the request. This tells the HTTP server that this particular request is actually a request to initiate a webSocket connection. This header also allows the web server to tell the difference between a regular HTTP request and a request to open a webSocket connection. This allows something very important in the architecture and it was done this way entirely on purpose. This allows the exact same server and port to be used for both serving your web requests and for webSocket connections. All that is needed is a component on your web server that looks for this Upgrade header on all incoming HTTP connections and, if found, it takes over the connection and turns it into a webSocket connection.

一旦服务器识别出这个 upgrade 标头,它就会以一个合法的 HTTP 响应作为响应,但一个向客户端发出信号表示已接受对 webSocket 协议的升级,如下所示:

Once the server recognizes this upgrade header, it responds with a legal HTTP response, but one that signals the client that the upgrade to the webSocket protocol has been accepted that looks like this:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

此时,客户端和服务器都将原始 HTTP 请求中的套接字保持打开状态,并且都切换到 webSocket 协议.

At that point, both client and server keep that socket from the original HTTP request open and both switch to the webSocket protocol.

现在,针对您的具体问题:

Now, to your specific questions:

我的应用程序如何与网络服务器和/或用于发送/接收数据的 WebSockets 库?

How does my application communicate with the web server and/or WebSockets library to send/receive data?

您的应用程序可能会在现代浏览器中使用内置的 webSocket 支持,并且可以像这样启动 webSocket 连接:

Your application may use the built-in webSocket support in modern browsers and can initiate a webSocket connection like this:

var socket = new WebSocket("ws://www.example.com");

这将指示浏览器使用当前网页所连接的相同端口启动到 www.example.com 的 webSocket 连接.由于浏览器内置了 webSocket 支持,客户端会自动为您处理上述 HTTP 请求和升级协议.

This will instruct the browser to initiate a webSocket connection to www.example.com use the same port that the current web page was connected with. Because of the built-in webSocket support in the browser, the above HTTP request and upgrade protocol is handled for you automatically from the client.

在服务器端,您需要确保您使用的 Web 服务器具有传入的 webSocket 支持,并且该支持已启用和配置.因为一个 webSocket 连接一旦建立就是一个连续的连接,它根本就没有真正遵循 CGI 模型.必须至少有一个长时间运行的进程处理实时 webSocket 连接.在服务器模型(如 CGI)中,您需要某种 webServer 插件来支持您的 webSocket 连接的这个长时间运行的过程.在像 node.js 这样已经是一个长时间运行的进程的服务器环境中,添加 webSockets 在架构上根本没有变化 - 而只是一个额外的库来支持 webSocket 协议.

On the server-side of things, you need to make sure you are using a web server that has incoming webSocket support and that the support is enabled and configured. Because a webSocket connection is a continuous connection once established, it does not really follow the CGI model at all. There must be at least one long-running process handling live webSocket connections. In server models (like CGI), you would need some sort of webServer add-on that supports this long-running process for your webSocket connections. In a server environment like node.js which is already a long running process, the addition of webSockets is no change at all architecturally - but rather just an additional library to support the webSocket protocol.

我建议您可能会发现这篇文章很有趣,因为它讨论了从 CGI 风格的单一请求处理到 webSocket 的连续套接字连接的转变:

I'd suggest you may find this article interesting as it discussions this transition from CGI-style single request handling to the continuous socket connections of webSocket:

Web 演进:从 CGI 到 Websockets(以及它将如何帮助您更好地监控云基础架构)

如果你真的想坚持使用标准输入/标准输出模型,有一些库可以为你的 webSockets 建模.这是一个这样的库.他们的标语是20 年后,WebSockets 就像 CGI".

If you really want to stick with the stdin/stdout model, there are libraries that model that for your for webSockets. Here's one such library. Their tagline is "It's like CGI, twenty years later, for WebSockets".

我想弄清楚如何为此添加 WebSockets 支持.一世宁愿使用编译的解决方案而不是其他东西解释如 JavaScript、Python 或 PHP.

I'm trying to figure out how I can add WebSockets support to that. I would prefer to use a compiled solution as opposed to something interpreted such as JavaScript, Python or PHP.

抱歉,我不熟悉那个特定的服务器环境.可能需要进行一些深入的搜索才能找出您的选择.由于 webSocket 连接是连续连接,因此您将需要一个连续运行的进程,它可以作为 webSocket 连接的服务器端部分.这可以是您的网络服务器中内置的内容,也可以是网络服务器启动并将传入连接转发到的附加进程.

Sorry, but I'm not familiar with that particular server environment. It will likely take some in-depth searching to find out what your options are. Since a webSocket connection is a continuous connection, then you will need a process that is running continuously that can be the server-side part of the webSocket connection. This can either be something built into your webServer or it can be an additional process that the webServer starts up and forwards incoming connections to.

仅供参考,我在家里有一个基于 Raspberry Pi 的自定义应用程序,它使用 webSockets 与浏览器网页进行实时通信,并且运行良好.我碰巧将 node.js 用于服务器环境和运行在 webSockets 之上的 socket.io 库,以便在 webSockets 之上为我提供更高级别的接口.我的服务器代码定期检查多个硬件传感器,然后每当有新的/更改的数据要报告时,它就会向任何打开的 webSockets 发送消息,以便连接的浏览器获得传感器读数的实时更新.

FYI, I have a custom application at home here built on a Raspberry Pi that uses webSockets for real-time communication with browser web pages and it works just fine. I happen to be using node.js for the server environment and the socket.io library that runs on top of webSockets to give me a higher level interface on top of webSockets. My server code checks several hardware sensors on a regular interval and then whenever there is new/changed data to report, it sends messages down any open webSockets so the connected browsers get real-time updates on the sensor readings.

您可能需要一些长时间运行的应用程序,将传入的 webSocket 连接从 Web 服务器传递到您长时间运行的进程,或者您需要在与 Web 服务器不同的端口上建立 webSocket 连接(因此它们可能是由完全不同的服务器进程部署)在这种情况下,您将拥有一个完整的独立服务器来处理您的 webSocket 请求和套接字(该服务器还必须支持 CORS 以使浏览器能够连接到它,因为它将是一个不同的端口您的网页).

You would likely need some long-running application that incoming webSocket connections were passed from the web server to your long running process or you'd need to make the webSocket connections on a different port than your web server (so they could be fielded by a completely different server process) in which case you'd have a whole separate server to handle your webSocket requests and sockets (this server would also have to support CORS to enable browsers to connect to it since it would be a different port than your web pages).

这篇关于WebSockets 服务器架构如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆