WebSockets服务器体系结构如何工作?

时间:2015-05-12 19:52:40

标签: websocket libwebsockets

我试图更好地了解服务器端架构如何为WebSockets工作,目标是在嵌入式应用程序中实现它。这里似乎有3种不同的服务器端软件组件:1)Web服务器提供静态HTTP页面并处理升级请求,2)WebSockets库如libwebsockets来处理"螺母和螺栓&# 34; WebSockets通信,3)我的自定义应用程序,以实际弄清楚如何处理传入的数据。这些如何组合在一起?是否有一个单独的Web服务器和WebSocket处理块,又称WebSocket服务器/守护进程?

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

这就是我要问的原因。我在具有有限内存的Blackfin处理器上的uClinux / no MMU平台上使用boa Web服务器。 boa中没有本机WebSocket支持,只有CGI。我试图找出如何添加WebSockets支持。我更喜欢使用编译的解决方案,而不是像JavaScript,Python或PHP这样的解释。我当前的应用程序使用CGI的长轮询,这不能为计划的增强提供足够的性能。

1 个答案:

答案 0 :(得分:35)

首先,了解如何建立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服务器上的一个组件,它在所有传入的HTTP连接上查找此Upgrade标头,如果找到,它将接管连接并将其转换为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");

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

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

我建议您在讨论从CGI样式的单一请求处理到webSocket的连续套接字连接的过渡时,可能会发现这篇文章很有趣:

Web Evolution: from CGI to Websockets (and how it will help you better monitor your cloud infrastructure)

如果你真的想坚持使用stdin / stdout模型,那么有些库可以为你的webSockets建模。这是one such library。他们的标语是"它就像CGI,二十年后,对于WebSockets"

  

我试图找出如何添加WebSockets支持。一世   宁愿使用编译的解决方案而不是某些东西   解释如JavaScript,Python或PHP。

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

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

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