百度空间 | 百度首页 
               
 
查看文章
 
comet server之java实现:asyncweb,jetty,tomcat
2008-03-29 16:42
前不久自己用C实现的comet http server,基于libevent,用c实现了一个comet server原型,由于libevent封装了一个http协议实现,代码比较简洁,但不简单。最近又了解了一下Java的实现方案。
  • Java中目前有2种选择,一种是基于Apache MINA框架的,稍复杂但适合用在大场合;一种是基于Java Web容器自己提供的支持,如Jetty和Tomcat,适合comet只是应用中一小部分场合。
  • Mina只是个网络层(相当socket层)的框架,如果用mina需要自己实现HTTP协议。好消息是这个工作已经有开源做了,一个叫Asyncweb项目在mina的基础上实现了HTTP协议层的封装。而且asyncweb正在被mina合并,将加入到mina的发行版中。
用asyncweb编程很简单,只需实现一个接口,实际上只需要实现 handleRequest, 在 request 返回结果。
public interface HttpService
{
void handleRequest( HttpServiceContext context ) throws Exception;

void start();

void stop();
}
  • 经过测试,asyncweb适合做异步long pooling,但不适合做Streaming XHR, 参看一下例子
handleRequest 例子,不管是同步还是异步,都必须一步输出,不支持一次写一部分
/** 同步处理的例子 */
public void handleRequest( HttpServiceContext context ) throws Exception {
MutableHttpResponse response = new DefaultHttpResponse();

StringWriter buf = new StringWriter();
PrintWriter writer = new PrintWriter(buf);
writer.println("test");
writer.flush();

IoBuffer bb = IoBuffer.allocate(1024);
bb.setAutoExpand(true);
bb.putString(buf.toString(), Charset.forName("UTF-8").newEncoder());
bb.flip();
response.setContent(bb);

response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setStatus(HttpResponseStatus.OK);

context.commitResponse(response);
}

/** 异步处理的例子,可以不马上返回,但是必须一次返回 */
public void handleRequest( HttpServiceContext context ) throws Exception {
context.addClientListener( new HttpClientListener() {
public void clientDisconnected( HttpServiceContext ctx ) {
}

public void clientIdle( HttpServiceContext ctx, long idleTime, int idleCount ) {
// do something...
// context.commitResponse(...)
}
});
}

所以Asyncweb如果需要Streaming XHR功能还需要修改source code,所以目前成熟的做法还是用Jetty or Tomcat,另外在网上见到说GlassFish中的Grizzly使用修改了asyncweb实现了comet功能,或许那个1年多前的修改版本更值得借鉴。

Jetty 的Comet实现从编程的角度是最简单的,suspend的时候本次执行就结束了。
public class ForeverFrameJettyServlet extends HttpServlet {
public void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// handle the time request
if (req.getRequestURI().endsWith("/time")) {
// get the jetty continuation
Continuation cc = ContinuationSupport.getContinuation(req, null);

// set the header
resp.setContentType("text/html");

// write time periodically
while (true) {
cc.suspend(1000); // suspend the response
resp.getWriter().println("test");
resp.getWriter().flush();
}
}

// ...
}
}

Tomcat6 也支持Comet,需要实现一个CometProcessor接口,稍繁琐。例子可参考下面Resource1

Resource:
1. Asynchronous HTTP and Comet architectures
An introduction to asynchronous, non-blocking HTTP programming
http://www.javaworld.com/javaworld/jw-03-2008/jw-03-asynchhttp.html

2. AsyncWeb Performance Test 与Apache2性能比较

类别:Web Im | 添加到搜藏 | 浏览() | 评论 (3)
 
最近读者:
 
网友评论:
1
2008-03-30 23:44 | 回复
兄弟好深.
 
2
2008-05-10 11:48 | 回复
~着正式我需要的 谢谢你
 
3
2008-05-23 12:43 | 回复
好!
 
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu