关于Jetty6.0服务器的Continuations

Jetty6.0提供了AJAX的服务器端的推的技术,而且采用的是JAVA非阻塞的I/O,可以保证"Thousands of users can be served with hundreds of connections”,在学习DWR2的时候,也有类似服务器的推技术,对于这种技术是基于HTTP1.1的长连接进行的,但是网上关于这个方面的资料不是很多,仅仅从理论的角度进行讲解,请教banq能否 通过一个简单的技术模拟下这种服务器的长连接(并不是轮询的方式),将服务器的数据推到客户端,并且不占用当前的请求线程,他们的实现机制是如何的?目前仅仅有感性认识,主要问题是服务器如何得知需要更新的客户。请bang详细阐述一下,谢谢

jetty服务器这种长连接Continuations 其实不是真正的长连接,应该叫'connection freezing', or 'request parking' 连接暂停或请求暂停。

对于PUSH推机制:对于Jetty6其实还是依靠AJAX的客户端主动请求的,改善的是:不需要AJAX客户端不断发出多次请求给服务器,以确定服务器端是否有响应。服务器端hold住ajax客户端第一次请求,如果没有业务结果,就不发出响应response,也就是说不关闭这次http连接,但是因为一个连接一个线程,你保持住一个请求就象保持一个线程一直运行,这是很浪费资源的。

传统socket模式都是一个connection一个线程,NIO可以通过事件机制再触发新线程,使得线程和请求可以分离,这样, Jetty就是利用NIO这个机制,保持住请求request对象,释放原来支持该请求的线程,让线程返回线程池,这样,如果业务处理有结果,Jetty就向客户端发出响应,否则一直保持直至timeout失效。

这个机制如果证明可行,会加入servlet 3.0新规范,到时所有Jee服务器都有这个功能。

所以,这个机制不是严格意义上的推机制,但是也可以对付大量频繁刷新请求,所以是一个改进。

至于推机制中服务器如何推,可以参考eda架构,这个是和我们平时做的JEE的SOA机制不太一样,至于如何推,可以使用线程提醒 观察者JDK 或JMS等等。

http://www.theserverside.com/news/thread.tss?thread_id=36594

http://docs.codehaus.org/display/JETTY/Continuations

听banq解释后,对这个推技术有所了解了,但是遵循HTTP1.1协议的应用是长连接的,虽然保持了客户与服务器的连接,但是类似DWR这样的反向AJAX如何知道将推向他们数据的客户端呢?这样就达到了时时的数据更新,可以保证用户不用操作垃圾数据。可否解释下对于DWR这样的把更新数据推向客户的推是如何推到正确的用户的,服务器端如何保留对客户端的ID的引用的?谢谢

我们所理解的长连接一般是:浏览器和服务器一直保持连接,然后服务器端push数据到浏览器,但实际上DWR2和Jetty6都不是这样,事实上也很难做到。

你说的是DWR2的Reverse Ajax 特性吧,它提供三种push方式:
Polling 最常见的不断反复请求
Comet 需要jetty6这样服务器支持,将一个请求一直保持住。能留多长留多长
Piggyback 这是一个特点,服务器将需要推送的数据在客户端发出的另外一次连接中一起传到客户端,相当于客户端收到两个响应,两个响应一起送达。

这三种方式各有利弊,根据情况选取。Piggyback 问题就在于需要等待下次请求,如果客户端的下次请求连接等10分钟后才发出,那么服务器推送的数据就没有及时性了;但是它是最低负载的。

http://directwebremoting.org/dwr/reverse-ajax

问题 一:
对于采用POLLING 的方式,有点类似于JS中的setInterval()这个方法吧,间隔多长时间就执行函数,这个函数也就是对后台的请求处理函数,不知道这么理解是否恰当。
问题二:
再者,在DWR DEMO中的chat的例子中,是将连接同一个页面的客户ID保存在服务器端,然后当有数据更新的时候,通知所有的同一页面的客户,这个保存客户页面ID是如何做的,又是如何通知到所有的客户端页面更新的,我对这个地方比较感兴趣,也感觉挺神秘的,banq能否把这个原理以及基本的实现伪代码说下,光是理论的还是感觉很茫然,实现的核心点在哪里,我个人感觉更新发送请求的客户的数据很正常,但是更新处在同一页面下的客户的信息就不知道如何实现了!请赐教!
问题三:
>>Piggyback 这是一个特点,服务器将需要推送的数据在客户端发出的另外一次连接中一起传到客户端,相当于客户端收到两个响应,两个响应一起送达
这个不是特别的明白,为什么说是两次请求?请详细解释下,谢谢!(一遍一遍的问,自己都感觉不好意思了,实在是太笨,但是是对知识的渴求,呵呵)
虽然来JDON时间不长,但是确实被这里的氛围所感染,并且对banq的细心的回答很感激!

[该贴被yongbuyanbai于2008-08-07 15:44修改过]

没有关系,讨论清楚对大家都有好处。

POLLING你的理解基本正确。

问题二:
服务器端保存的是AJAX request这个对象,每个客户端的request都会被服务器挽留住了,这里采取类似线程暂停的方式,当另外客户端有发送给其他客户端,就会踢醒这个暂停。

>banq能否把这个原理以及基本的实现伪代码说下,光是理论的还是感觉很茫然
这里基本就是采取观察者模式。可了解observer模式相关代码就不觉得茫然了。所以,掌握模式,可以帮助我们填补设计理论和代码之间的空白,从而能够抽象讨论问题,有不失去代码实现的可能。所以,模式思维是每个人必备的。

至于客户端ID是保存是如何实现,这涉及具体业务了,每个客户端进入chat room总要留下ID和IP等信息,你保存在内存中即可。


>为什么说是两次请求
没有说两次请求request,是两次响应response,打个比喻:你和你爸妈在两个地方,有亲戚从家乡来你住的地方,那么爸妈就把上次你春节回家忘记带的东西一起托亲戚带给你,这就是将两次响应在一次连接中送出,亲戚来你家有他自己的事,他还带上上次响应的时来。


[该贴被banq于2008-08-08 12:56修改过]
[该贴被banq于2008-08-08 12:57修改过]

HTTP协议本身是一个无连接协议,所以想实现异步处理很麻烦,代价估计就是长连接,长时间占用端口。