近来由于毕业设计,一直在忙于comet技术的研究,有了一些心得和想法,特来与大家分享。
Comet技术被称为下一代Ajax技术,主要通过实现server push来解决ajax需要定时频繁发送请求的问题。
通过Comet技术,客户端所需要的response信息不再需要主动的去索取,而是在服务器端以event的形式推至客户端。
Comet 技术常见的实现方式
streaming和long polling
long poll:HTTP的连接保持,直到server端一个事件触发或者到达timeout事件。client端在收到response消息后,一个新的 HTTP请求会立刻开放。通过这种方式,server端可以将数据在任何时候push到客户端。
streaming:在streaming方式中,HTTP的连接是始终保持的,即使客户端收到响应,HTTP连接也不断开。
Tomcat 与Comet
??????在Tomcat 6中,增加了对Comet的支持,但是其自带例子(/webapps/examples/jsp/chat)有很多问题,没有运行成功,怀疑该例并不完整 (我的版本Tomcat 6.0.16),经过学习和研究,发现了一些问题,希望能给仍然奋战在其中的朋友一些帮助。
??????前期准备: 使用tomcat提供的comet api之前,需要增加对NIO的支持,配置nio可是相当方便,要做的仅仅是在server.xml里边修改connector:
<connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="8080" redirectport="8443" connectiontimeout="20000">
??????Tomcat 6提供了CometProcessor和CometEvent接口,具体功能和操作不再赘述,详情请见http://tomcat.apache.org/tomcat-6.0-doc/aio.html 。 注意:实现CometProcessor接口后不用在servlet中写doGet,doPoset方法,所有事件在 BEGIN,READ,END,ERROR中实现。
??????简单的Comet servlet代码示例:
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->?1 ?import ?java.io. * ;
?2 ?import ?javax.servlet.ServletException;
?3 ?import ?javax.servlet.http. * ;
?4 ?import ?org.apache.catalina.CometEvent;
?5 ?import ?org.apache.catalina.CometProcessor;
?6 ?import ?org.apache.catalina.CometEvent.EventType;
?7 ?
?8 ?public ? class ?cometServlet? extends ?HttpServlet? implements ?CometProcessor?{
?9 ????
10 ????????? public ? void ?event(CometEvent?e)? throws ?IOException,?ServletException?{
11 ???????????????? if (e.getEventType()? == ?EventType.BEGIN)?{
12 ??????????????????????? // ?fill?in?code?handling?here
13 ????????????????????HttpServletResponse?response? = ?e.getHttpServletResponse();
14 ????????????????????PrintWriter?out? = ?response.getWriter();
15 ????????????????????out.write( " Hello?world " );
16 ????????????????????out.flush();?
17 ???????????????????? // System.out.println("message?sent");
18 ????????????????}
19 ???????????????? if (e.getEventType()? == ?EventType.READ)?{
20 ??????????????????? // ?fill?in?code?handling?here
21 ????????????????}
22 ???????????????? // ?and?continue?handing?other?events
23 ?????????}
24 ?}
在此源代码中,仅完成向客户端发送Hello World字符串的功能,关键点,out.flush()不可缺少,以往在写ajax程序的时候,往往忽略写这句话,但这里如果不写,客户端无法收到响应 文字。由于tomcat采用streaming的方式实现comet,不知是否不加这句话的时候,客户端不知道你的消息已经结束,而始终处于一个等待的状 态(如果您有更专业的解释,请指教)。
??????服务器端javascript相关代码:
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->?1 ?< script >
?2 ?function?CometEx()?{
?3 ???var?request? = ?? new ?XMLHttpRequest();
?4 ???request.open( " GET " ,? ' http://localhost:8080/cometEx/cometServlet ' ,? true );
?5 ???request.onreadystatechange? = ?function()?{
?6 ????? if ?(request.readyState? == ? 3 ? && ?request.status? == ? 200 )?{
?7 ????????????alert(request.responseText);?????
?8 ?????}
?9 ???}
10 ???request.send( null );
11 ?}
12 ?</ script >
服务器端代码类似与普通Ajax代码,其中,需要注意的是:request.readyState值如果设置为4,浏览器会处于长期等待状态,而收不到响 应消息,设置为3后,firefox浏览器正常,但IE不能正常获得消息,由于在学习过程中,要求只用到firefox浏览器,并未对IE浏览器进行更深 一步的研究(希望高手可以提供IE浏览器解决方案,谢谢)。