🔗 请求队列
🔗 是什么?
storework 分支的一个重要产出是需要对请求和回复的处理方式进行规范。我之前的一个想法(听起来很像我 2000 年的 clientlet/servlet)是关于消息和请求队列的。
本质上,不再是完全依赖回调驱动,请求/回复/数据交换被转化为类似队列消息和请求的东西。“客户端”和“服务器”只是请求的端点,可以通过不同的处理层进行连接,以实现 Robert 的 clientstreams API。
🔗 如何工作?
这非常 C 语言导向。将这些想法转化为 C++ 类抽象不会太困难。
🔗 请求
请求是一个可排队的实体。它有两个端点——一个客户端(即连接/访问服务器)和一个服务器(即接受/访问客户端)。这些是抽象的消息队列和回调(或者对于 C++,是类实现),它们负责繁重的工作。这里的想法是抽象出网络客户端和服务器的概念;而是允许服务器是本地的(例如,缓存),客户端也是本地的(例如,ESI 处理)。
请求由服务器创建,代表一个 HTTP 请求。它不一定仅仅是 HTTP 请求,但我们目前是一个 HTTP 代理,所以就是 HTTP。它包含来自服务器的所有相关信息(方法/URL/版本、客户端凭证、认证凭证等)。请求被放入“新的 HTTP 请求”队列。
队列运行程序将扫描待处理的请求队列并决定如何操作。在代理的情况下,它会想要找到或创建一个客户端来满足请求。一旦请求以某种方式得到满足,它将被附加到一个客户端,形成数据管道的另一端。请求移至“进行中的 HTTP 请求”队列并开始数据交换。一旦客户端和服务器双方
- 都与请求解除关联,请求就会被销毁。
🔗 消息
一般的交换应该涉及简单的消息。有几种消息类型:
- “请求”消息类型 - 方法、URL、版本
- “回复”消息类型 - 状态
- “标头”消息类型
- “请求正文块”消息类型
- “回复正文块”消息类型
- “状态”消息类型 - 例如,REQUEST_OK、REPLY_OK、HEADERS_OK、REQBODY_OK、REPBODY_OK、REQBODY_EOF、REPBODY_EOF、REQBODY_WANTMORE、REPBODY_WANTMORE
请求消息类型可能不是必需的——整个请求信息应该是 HTTP 请求本身的一部分,因此在客户端实现被要求处理请求时即可获得。
GET 数据流示例
- 客户端排队 HTTP 请求
- 队列实现最终将请求与服务器关联起来
- 服务器发送“我在这里,欢迎,我们开始吧”消息
- 客户端发送“好的,我们开始吧”消息
- 服务器向客户端发送“回复”+“标头”+“回复正文块”消息
- 客户端向服务器发送“回复确定”+“标头确定”+“回复正文块确定”+“需要更多”消息
- 服务器发送“回复正文块”+“回复正文 EOF”消息
- 客户端向服务器发送“回复正文确定”+“EOF 确定”+“请求完成”消息
- 服务器解除与请求的关联
- 客户端解除与请求的关联
- 请求出队
POST 数据流(或任何带有请求正文的)示例
- 客户端排队 HTTP 请求
- 队列实现最终将请求与服务器关联起来
- 服务器发送“我在这里,欢迎,我们开始吧”消息
- 客户端发送“好的,我们开始吧”+“请求正文块”消息
- 服务器发送“请求正文确定”+“需要更多”消息
- 客户端发送“请求正文块”+“请求正文 EOF”消息
- 服务器发送“请求正文确定”+“请求正文 EOF 确定”消息
- 此时客户端正在等待状态消息
- 服务器发送“回复”+“标头”+“回复正文块”+“回复正文 EOF”消息
- 客户端发送“回复确定”+“标头确定”+“回复正文块确定”
- “回复正文 EOF 确定”+“请求完成”消息
- 服务器解除与请求的关联
- 客户端解除与请求的关联
- 请求出队
🔗 需要注意的事项
- 对于小对象,它应该轻量级——尽量将尽可能多的请求正文包含在第一条消息中,并尽量将尽可能多的回复正文与回复状态一起包含。
- 请注意,这只是请求——客户端和服务器连接必须实现自己的状态引擎来实现持久化等。
- 我没有涵盖任何类似固定连接支持的内容,但支持它并不难(就像 Squid 有的那样,只需有一个“此连接固定到此连接”的标志)。