BOSH 是一种传输协议,它通过高效地使用多个同步的 HTTP 请求/响应对,而无需使用频繁的轮询和分块响应的方式,在两个实体(比如,客户端和服务端)间,模拟常驻的、双向的 TCP 连接的语义。
BOSH 运用的技术有时被称为"HTTP 长轮询",与其它 HTTP 轮询技术相比,BOSH 减少了延迟和带宽消耗。当客户端发送请求时,连接管理器不立即发送响应;而是保持请求打开,直到真正地有数据发送给客户端(或已经过去约定的非活跃时间)。然后,客户端立即向连接管理器发送新请求,继续长轮询循环。
如果连接管理器在约定的时间长度后,没有任何数据要发送给客户端,那么它将发送带有空 <body/> 的响应。这与空白保活或 XMPP Ping(XEP-0199)的目的类似;有助于保持套接字连接处于活跃状态,防止一些中间设备(防火墙、代理等)静默地丢弃它,并且有助于在合理的时间内,检测连接是否中断。
当客户端和连接管理器支持持久连接时(HTTP/1.0 的 “Connection: keep-alive”,其为 HTTP/1.1 的默认状态),这些套接字保持打开一段时间,等待客户端的下一个请求。这减少了套接字建立的开销,如果使用基于安全套接字层(SSL)的 HTTP,那么开销可能非常大。
如果客户端在请求仍然打开时,有数据要发送,那么它将建立第二个到连接管理器的套接字连接,以发送新请求。连接管理器立即响应先前持有的请求(可能没有数据),并且保持新请求打开。这导致连接的角色切换;“旧”连接被响应,并且等待新请求,而“新”连接现在用于长轮询循环。
下图说明了该技术(可能是在建立 XMPP 会话之后)
xxxxxxxxxx
(timeline running top-down)
first socket second socket
|
+-+ <-- empty body request
|X|
|-|
| |
| |
| |
| |
|-| <-- empty body response
|*|
+-+
|
+-+ <-- empty body request
|X|
|-|
| |
| |
| |
| |
|-| <-- empty body response
|*|
+-+
|
+-+ <-- empty body request
|X| socket opened --> ===
|-| |
| | new message out --> +-+
|-| <-- empty body response |X|
|*| |-|
+-+ | |
| | |
| | |
| | |
| empty body response --> |-|
| |*|
| +-+
| |
| empty body request --> +-+
| |X|
| |-|
| | |
+-+ <-- new message out | |
|X| empty body response --> |-|
|-| <-- new message in |*|
|*| +-+
+-+ |
| |
+-+ <-- empty body request |
|X| |
|-| |
| | |
| | new message out --> +-+
|-| <-- new message in |X|
|*| |-|
+-+ | |
| | |
| | |
| | |
| empty body response --> |-|
| |*|
| +-+
| |
| empty body request --> +-+
| |X|
| |-|
| | |
| | |
| | |
| | |
| empty body response --> |-|
| |*|
| +-+
| |