`
shallon
  • 浏览: 72272 次
  • 性别: Icon_minigender_2
  • 来自: 0
文章分类
社区版块
存档分类
最新评论

初探BOSH (Bidirectional-streams Over Synchronous HTTP)

阅读更多
简述:
    BOSH (Bidirectional-streams Over Synchronous HTTP)是一种在客户端和服务器端之间通过HTTP的请求/响应进行客户端和服务器双向通信的技术,BOSH在XMPP系列规范中的XEP-0124中定义,应用场合为基于浏览器的客户端访问XMPP服务器。 下面的内容来自XEP-0124规范。http://www.xmpp.org/extensions/xep-0124.html
其具体应用需求:
1、  能够在手机或者浏览器的运行环境中使用**
2、  浏览器中的客户端能够建立双向的跨域的连接*
3、  兼容缓存部分HTTP Response的HTTP 代理 *
4、  快速通过有HTTP Response生存时间限制的代理 *
5、  兼容HTTP1.0 *
6、  兼容受限的网络连接环境(防火墙、代理、网关)
7、  容错性
8、  扩展性
9、  更小的带宽消耗
10、更快的实时响应时间
11、 支持轮询
12、 按顺序提交数据
13、防止Session中有非法插入的请求(interjecting HTTP requests into a session)
14、防止拒绝服务攻击
15、多路复用的数据流

    在规范中声称:打了*号的几项是无法用COMET技术实现(就是2、3、4、5),经过考察,作者是将COMET定义为流的方式推送数据的HTTP长连接技术。因此,无法通过缓存HTTP响应、及有生存时间限制的HTTP代理。另外由于HTTP1.0无法支持块数据的编码(chunked transfer encoding)流的方式推送数据无法在HTTP1.0的环境下使用。(至于第2条,规范作者用了非常奇怪的方式去企图建立跨域的连接,俺决定放弃不追究作者在说啥)要了解HTTP长连接技术,建议看:http://www.ibm.com/developerworks/cn/web/wa-lo-comet/index.html

系统架构:

在架构中,连接管理器(Connection Manager)与 Server之间是原始的数据流(在XMPP的协议中就是XMPP的数据流),HTTP客户端与连接管理器之间是HTTP协议以及BodyTAG封装的数据流。

<o:p> </o:p>

流程描述:

BOSH技术能够同时减小网络带宽和减小客户端响应的时间。其方案是对客户端的请求连接管理器不给于返回直到数据已经就绪,当客户端收取连接管理器返回的数据会向连接管理器发送下一个请求,于是连接管理器总是保持着一个客户端的请求,当服务器端数据就绪的时候,可以将数据封装在请求的响应包中,“推送”给客户端。

<o:p> </o:p>

如果双向连接长时间没有数据,连接管理器负责给客户端发送一个空包,空包触发客户端发送新的请求,连接管理器通过这种机制判断连接是否已经中断,由于BOSH不是轮询的机制,带宽消耗比标准的TCP连接大不了多少。


由于大多数的客户端不支持HTTPPipeling(单一的连接上承载并发的请求),于是,客户端必须从第二条HTTP连接发送消息。当第二条HTTP连接有新的请求发送的时候,连接管理器将第一条连接中的请求返回,即便此时第一条连接中的返回的是空数据包。这样做的原因是让客户端有需要的话可以发送新的请求过来。客户段同一时间最多只能保持两条HTTP连接,否则的话,客户端必须等待旧的请求处理完之后才能发送新的请求

在网络经常中断的环境下,BOSH退化成每个数据请求一个新HTTP连接。然而,在通常情况下,网络环境良好,客户端可以使用http/1.1,这个时候,一个Session包含两个TCP长连接,所有的请求都在这两个长连接上传输。基本上任何时候,客户端通过一条连接能够推送数据到服务器,与此同时,服务器端可以“推送”数据到客户端。值得注意的是,这两条长连接的角色在客户端每发送一次请求则角色转换一次。


<o:p> </o:p>尽管大多数时间可以随时推送数据到对端,但是,如果一方刚刚推送完数据,则需要等一个网络来回的时间才能推送下一个数据

分享到:
评论
12 楼 birdjavaeye 2007-10-02  
歆渊 写道

在没有客户端没有发送请求的时候 这个没看太明白. 我设想的情况是这样: 建立这个长HTTP连接时是客户端发出一个空的HTTP请求, 不提交任何请求数据, 只为建立这条HTTP连接; 如果没有数据需要push 服务器可以在连接TimeOut之前不给客户端传任何数据. 然后针对 HTTP/1.1, 可以在快要TimeOut的时候发一个空包维持此连接; 或者可以与 HTTP/1.0 的处理相同, 直接0长度内容结束这条连接, 然后等着客户端发起另外一个 "长连接".


在没有数据这一点上,和bosh是一致的心跳方式
而在客户端有数据发送时,和bosh就不同了,更简单一些
但是问题在于proxy和cache:即使是chunk,proxy cache也可以等所有数据全部接收到了,缓存起来了,再一次性返回给客户端,这样就破坏了这个长连接本来的目的
bosh中response肯定只是一个包,所以能很好地适应proxy和cache
11 楼 zgd 2007-09-29  
支持BOSH
10 楼 shallon 2007-09-27  
1、BOSH的规范中没有声明是为无线互联网设计的(只说是兼容移动终端),实际上作为XMPP的系列规范,肯定在有线互联网也有主流的应用。实际上,几个主流开源的XMPP服务器都对BOSH(以前版本叫做HTTP-BIND)有支持。正如规范中所言,HTTP1.1的环境下才是BOSH性能最优的时候。
2、不清楚“http1.1的chunk encoding方式实现的长连接 ”与“HTTP Stream”有什么区别?当数据需要分块编码传输的时候,这时候是否可以看作是HTTP的Stream?

9 楼 andyluan 2007-09-26  
BOSH的方式其实是被设计来作为无线互联网应用场景的。在有线互联网的稳定快速连接中没有什么优势。在中移动的CMWAP和CMNET中,所谓的"长连接“是通不过porxy的,移动网关对于http request的最大超期时间设置很短,北京移动这边的CMNET大约为50秒,同时也不支持http1.1的keepalive和chunk encoding.
    PC上大家实现长连接的几种方式:
一、http1.1的chunk encoding方式实现的长连接
二、http1.1的keepalive
三、HTTP Streaming

8 楼 歆渊 2007-09-24  
shallon 写道
一条HTTP长连接在没有客户端没有发送请求的时候不断的有数据从服务器push到客户端,我不是很明白您的场景。如果push的不是一个完整的http包,而是HTTP包中的一个数据块,这是流的方式实现长连接,这种情况规范中分析了不能穿透一些proxy(有些proxy会等待完整的HTTP包再转发)。如果push的是一个完整包,这个不可能,因为客户端发送了请求给服务器端,当收到服务器端200ok的回应包时候就认为请求处理完了。客户端不会再等待其他的200ok的包(否则这个协议的请求和响应就对应不上了)。


在没有客户端没有发送请求的时候 这个没看太明白. 我设想的情况是这样: 建立这个长HTTP连接时是客户端发出一个空的HTTP请求, 不提交任何请求数据, 只为建立这条HTTP连接; 如果没有数据需要push 服务器可以在连接TimeOut之前不给客户端传任何数据. 然后针对 HTTP/1.1, 可以在快要TimeOut的时候发一个空包维持此连接; 或者可以与 HTTP/1.0 的处理相同, 直接0长度内容结束这条连接, 然后等着客户端发起另外一个 "长连接".
7 楼 shallon 2007-09-24  
一条HTTP长连接在没有客户端没有发送请求的时候不断的有数据从服务器push到客户端,我不是很明白您的场景。如果push的不是一个完整的http包,而是HTTP包中的一个数据块,这是流的方式实现长连接,这种情况规范中分析了不能穿透一些proxy(有些proxy会等待完整的HTTP包再转发)。如果push的是一个完整包,这个不可能,因为客户端发送了请求给服务器端,当收到服务器端200ok的回应包时候就认为请求处理完了。客户端不会再等待其他的200ok的包(否则这个协议的请求和响应就对应不上了)。
6 楼 歆渊 2007-09-24  
服务器端HOLD住才能变成长连接呀(不然是短连接轮询啊), 这条长连接就只是downlink, 只用来接收服务器push的下行数据; 要继续发送信息, 就新开另外的短连接呀, 可以通过客户端或者服务器端的一个队列来串行化这些短连接来防止插入.

另外基于HTTP的特性, 即使是长连接, 客户端也应该只发送一次请求数据, 不该有多次roundtrip, 否则proxy/cache的通过性应该就要打折扣了.
5 楼 shallon 2007-09-24  
只有一个长连接,如果服务器端不HOLD住请求,这是普通的轮询,浪费了大量的带宽。如果服务器端HOLD住请求,这时候这个连接不能用来继续发送信息直到服务端返回(不支持HTTP Pipelining)。BOSH考虑了后者的情况,添加多了一条连接。至于为什么是两条连接而不是更多,HTTP 1.1的规范中有:

Clients that use persistent connections SHOULD limit the number of simultaneous connections that they maintain to a given server. A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy. A proxy SHOULD use up to 2*N connections to another server or proxy, where N is the number of simultaneously active users. These guidelines are intended to improve HTTP response times and avoid congestion.
4 楼 歆渊 2007-09-24  
我考虑可以一个长 HTTP 连接只负责 服务器->客户端 的downlink, 然后 客户端->服务器 的uplink也是单向, 采用按需的短 HTTP 连接. 这样只需要一个长连接, 也具有同样的穿透HTTP PROXY/CACHE的能力, 同时可以退化为 HTTP/1.0, 是不是更好呢?

这种方式相比于 BOSH 有什么不好的地方?
3 楼 shallon 2007-09-24  
TO hongliang:没有具体的场景就没有最好实践。
不可否认BOSH实际上是一种长轮询的技术,但是这种技术的好处也是显而易见的。
1、兼容极端的网络环境,上文所述,穿透各种proxy、网关和http1.0的能力最强,可以退化成每个请求一个连接
2、在http1.1环境下也可以利用http1.1的优点

2 楼 江南白衣 2007-09-24  
支持shallon,支持Comet
1 楼 hongliang 2007-09-23  
BOSH并不是最好的comet实践,有狠大的改进余地

相关推荐

Global site tag (gtag.js) - Google Analytics