首先,让我们澄清一下我们在说什么:
gevent 是一个允许轻松编程事件循环的库。这是一种在不“阻止”请求者的情况下立即返回响应的方法。
socket.io 是一个创建客户端的 JavaScript 库,可以保持与发送事件的服务器的永久连接。然后,库可以对这些事件做出反应。
greenlet 认为这是一个线程。一种启动多个执行某些任务的工作人员的方法。
整个过程的高度简化概述如下:
假设您正在创建一个聊天客户端。
您需要一种在有人键入消息时通知用户屏幕的方法。为此,您需要以某种方式告诉所有用户何时显示新消息。这就是 socket.io 所做的。你可以把它想象成一个调谐到特定频率的收音机。每当有人在这个频率上传输时,代码就会做一些事情。对于聊天程序,它会将消息添加到聊天框窗口。
当然,如果您将收音机调谐到某个频率(您的客户),那么您需要一个广播电台/dj 来在该频率上进行传输。这是您的烧瓶代码的用武之地。它将创建“房间”,然后传输消息。客户端监听这些消息。
您也可以使用 node 在 socket.io 中编写服务器端(“广播电台”)代码,但这超出了这里的范围。
这里的问题是传统上 - Web 服务器是这样工作的:
- 用户在浏览器中输入地址,然后按 Enter(或 go)。
- 浏览器读取网址,然后使用DNS系统,找到服务器的IP地址。
- 它创建一个到服务器的连接,然后发送一个请求。
- 网络服务器接受请求。
- 它做一些工作,或启动一些进程(取决于请求的类型)。
- 它准备(或接收)来自进程的响应。
- 它将响应发送给客户端。
- 它会关闭连接。
在 3 和 8 之间,客户端(浏览器)正在等待响应 - 它被 阻止 执行任何其他操作。因此,如果某处出现问题,例如某些服务器端脚本处理请求的时间过长,浏览器就会停留在白页上,并且加载图标会旋转。在整个过程完成之前,它什么也做不了。这就是网络的设计方式。
这种“阻塞”架构非常适合一对一通信。但是,对于多人保持更新,此阻止不起作用。
事件库 (gevent) 对此有所帮助,因为它们接受并且不会阻止客户端;他们立即发送响应,并在处理完成时发送。
但是,您的应用程序仍需要通知客户端。但是,由于连接已关闭 - 您无法与客户联系。
为了通知客户端并确保客户端不需要“刷新”,应该打开一个永久连接 - 这就是 socket.io 所做的。它打开一个永久连接,并且一直在监听消息。
- 所以工作请求从一端进来 - 被接受。
- 工作已执行并由其他程序生成响应(可能是同一程序或其他程序)。
- 然后,系统会发送一条通知“嘿,我已完成您的请求 - 这是回复”。
- 第 1 步中的人会监听此消息,然后执行某些操作。
下面是WebSocket 一个新的全双工协议,它支持所有这些收音机/dj 功能。
WebSockets 和 HTTP 之间的共同点:
- 在同一个端口 (80) 上工作
- WebSocket 请求以 HTTP 握手请求开始(upgrade header),然后转移到 WebSocket 协议 - 此时连接被移交给与 websocket 兼容的服务器 .
您的传统网络服务器所要做的就是监听这个握手请求,确认它,然后将请求传递到与 websocket 兼容的服务器 - 就像任何其他正常的代理请求一样。