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 --> |-|| |*|| +-+| |