`

Comet学习笔记(一)Tomcat与Comet

阅读更多
客户端接收代码:

function callback() //回调函数,对服务端的响应处理,监视response状态
{

if(req.readystate==4) //请求状态为4表示成功

  {

if(req.status==200) //http状态200表示OK

{
                     //所有状态成功,执行此函数,显示数据
}

         }
}

结果。。。。。没成功!!!

         用IE或FF(firefox)连接发送信息,接收数据的的IE或FF并没有任何数据显示出来。于是用sinffer录了一下网络包,发现数据其实已经从tomcat推下来了,也就是浏览器已经接受到了数据。为什么浏览器没有显示呢?。。。

先研究一下tomcat推下来数据吧,tomcat使用chunked编码方式来进行报文体的传输。chunked编码是HTTP/1.1 RFC里定义的一种编码方式,因此所有的HTTP/1.1应用都应当支持此方式。
    chunked编码的基本方法是将大块数据分解成多块小数据,每块都可以自指定长度,其具体格式如下(BNF文法):
    Chunked-Body   = *chunk            //0至多个chunk
                     last-chunk         //最后一个chunk
                     trailer            //尾部
                     CRLF               //结束标记符

   chunk          = chunk-size [ chunk-extension ] CRLF 
                        chunk-data CRLF
   chunk-size     = 1*HEX
   last-chunk     = 1*("0") [ chunk-extension ] CRLF

   chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
   chunk-ext-name = token
   chunk-ext-val  = token | quoted-string
   chunk-data     = chunk-size(OCTET)
   trailer        = *(entity-header CRLF)    

也就是当用chunked的返回数据时,最后需要有一个长度为0的数据包表明数据结束。而恰恰是comet的stream工作机制导致tomcat没有发送最后一个结束包给浏览器,浏览器认为数据没有接收完一直在等待,直到接收到最后一个包或者socket断开连接。

         知道了原因开始想解决办法。

首先想的是从服务器端解决。如果手动发一个chunked结束包不久可以了?后来发现发了结束包浏览器就会断开连接,要想服务器可以继续推数据只能重新建立连接,stream成long polling了。

服务器不行就从客户端想办法,既然IE认为数据没有接受全所以不会出发readystate==4这个状态,那我们用状态3可不可以呢?也就是改代码为:

function callback() //回调函数,对服务端的响应处理,监视response状态
{

if(req.readystate==3) //请求状态为4表示成功

  {

if(req.status==200) //http状态200表示OK

{
                     //所有状态成功,执行此函数,显示数据
}

         }
}

结果是firefox可以正常运行,IE还是不行提示“数据没有准备好“。看来FF和IE存在差别,经查资料FF是基于Gecko引擎的,IE 则是基于Trident的。基于Gecko引擎的浏览器都可以很好的处理这种情况。这种方法不能使用,毕竟IE占据了绝大部分的浏览器市场。而且opera、safari等其他浏览器对这个的支持也都不同。

         经过几天的研究又回到了很老的iframe解决办法上,通过iframe tomcat和IE能够正常的工作了(FF还是有问题,数据回来到现实有延迟。由于我们的客户端都是IE所以这点也可以接受了)。最后就剩下一个小问题,IE上的加载图标不停老在那里转。。。。。

经过搜索使用天才google工程师的解决办法,成功解决大功告成!

以下是google的代码:

<script type="text/javascript">

var comet = {

  connection   : false,

  iframediv    : false,



  initialize: function() {



       var userAgent = navigator.userAgent.toLowerCase();



       //alert(userAgent)

    if (/msie/.test(userAgent) && !/opera/.test(userAgent)) {



      // For IE browsers

      comet.connection = new ActiveXObject("htmlfile");

      comet.connection.open();

      comet.connection.write("<html>");

      comet.connection.write("<script>document.domain = '"+document.domain+"';<\/script> ");

      comet.connection.write("</html>");

      comet.connection.close();

      comet.iframediv = comet.connection.createElement("div");

      comet.connection.appendChild(comet.iframediv);

      comet.connection.parentWindow.comet = comet;

      comet.iframediv.innerHTML = "<iframe id='comet_iframe' src='./Demo'></iframe>";

    }



    if( /mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent) ) {

      // For Firefox browser

      comet.connection = document.createElement('iframe');

      comet.connection.setAttribute('id','comet_iframe');

      with (comet.connection.style) {

        left       = top   = "-100px";

        height     = width = "1px";

        visibility = "hidden";

        display    = 'none';

      }

      comet.iframediv = document.createElement('iframe');

      comet.iframediv.setAttribute('src', './Demo');

      comet.connection.appendChild(comet.iframediv);

      document.body.appendChild(comet.connection);



    }

    if (/webkit/.test(userAgent) || /opera/.test(userAgent)) {



           // for other browsers

      comet.connection = document.createElement('iframe');

      comet.connection.setAttribute('id',     'comet_iframe');

      comet.connection.setAttribute('src',    './Demo');

      with (comet.connection.style) {

        position   = "absolute";

        left       = top   = "-100px";

        height     = width = "1px";

        visibility = "hidden";

      }

      document.body.appendChild(comet.connection);



    }

  },



  // this function will be called from backend.jsp

  printServerTime: function (time) {

    $('abc').innerHTML = time;

  },



  onUnload: function() {

    if (comet.connection) {

      comet.connection = false; // release the iframe to prevent problems with IE when reloading the page

    }

  }

}

Event.observe(window,'load',comet.initialize);

Event.observe(window, 'unload', comet.onUnload);

</script>
分享到:
评论
1 楼 leo_soul 2010-09-07  
$('abc').innerHTML = time;
----------------------------------
js 用框架了 你怎么不标出来什么框架?

相关推荐

    comet4j 所需js以及comet4j-tomcat6.jar、comet4j-tomcat7.jar包

    这两个JAR文件包含了Comet4j与Tomcat集成所需的所有类和资源,使得Comet4j能够无缝地在Tomcat环境中运行。开发者需要将这些JAR文件添加到Tomcat的lib目录下,以便Tomcat在启动时自动加载,从而支持Comet4j的HTTP长...

    comet4j-tomcat6,comet4j-tomcat7,comet4j.js,以及一个样例

    Comet4J是一个Java库,专门用于在Tomcat应用服务器上实现Comet技术,这是一种用于创建持久性HTTP连接的方法,以实现实时Web应用程序。在传统的HTTP协议中,客户端和服务器之间的通信是基于请求-响应模型的,而Comet...

    comet4j-tomcat6.jar和comet4j-tomcat7.jar和comet4j.js

    Comet4j是一个Java库,专门用于在Tomcat应用服务器上实现Comet技术,这是一种用于创建持久性HTTP连接的方法,从而实现服务器向客户端推送数据的功能。这种技术在实时Web应用程序中非常有用,例如在线聊天、股票报价...

    comet4j-tomcat6.jar、comet4j-tomcat7.jar、comet4j.js

    - 首先,将对应的`comet4j-tomcat6.jar`或`comet4j-tomcat7.jar`部署到Tomcat的`lib`目录下,使其成为服务器的一部分。 - 然后,在应用的web.xml配置文件中添加必要的Comet4J配置,如设置监听器、过滤器等。 - 在...

    comet4j-tomcat7.jar

    comet4j消息推送所需的comet4j-tomcat7.jar包,comet4j-tomcat7.jar

    comet4j.js,comet4j-tomcat6.jar,comet4j-tomcat7.jar

    Comet4J(Comet for Java)是一个纯粹基于AJAX(XMLHTTPRequest)的服务器推送框架,消息以JSON方式传递,具备长轮询、长连接、自动选择三种工作模式 文件包含comet4j-tomcat6.jar , comet4j-tomcat7.jar , comet4j.js...

    comet4j+tomcat6+tomcat7并附完整版Demo

    【标题】"comet4j+tomcat6+tomcat7并附完整版Demo" 提供的是一种在Java后端与前端之间实现长连接通信的解决方案,主要涉及到的技术包括Comet4j、Tomcat 6和Tomcat 7。Comet技术是用于实现实时Web应用的一种方法,它...

    comet4j-tomcat7.jar comet4j.js

    Comet4j-tomcat7.jar 是专为Tomcat7定制的库,包含了Comet4j与Tomcat7集成所需的所有组件和适配器。 在`comet4j.js`中,我们可以找到客户端的JavaScript代码,用于与服务器端的Comet4j服务进行交互。这个文件通常...

    comet4j-tomcat6-tomcat7-jar包以及js文件

    这个压缩包包含了与Comet4j相关的几个关键组件,适用于Tomcat 6和7两个版本的服务器环境。让我们详细了解一下这些内容。 首先,`comet4j.js`是Comet4j的JavaScript客户端库,它提供了与服务器端进行交互的API。在...

    comet4j.js+comet4j-tomcat7jar包资源

    Tomcat 7是一个流行的开源Java应用服务器,支持Servlet和JSP标准,Comet4J利用其特性来实现 comet 技术。你需要将这个jar包添加到Tomcat的类路径(classpath)中,以便在服务器端运行Comet4J相关的代码。 2. `comet...

    comet4j-tomcat7.jar和comen4j.js

    本讨论将详细讲解Comet4J与Tomcat7的集成以及其核心组件。 1. **Comet4J技术概述**: Comet4J是基于HTTP长连接的技术,通过在服务器端保持一个开放的HTTP连接,直到有新的数据可推送给客户端为止。这与传统的HTTP...

    comet4j+tomcat7 demo

    【comet4j+Tomcat7 Demo】是一个用于展示如何在Tomcat7服务器上整合并使用Comet4j技术的示例项目。Comet4j是一个开源的Java库,专门设计用于实现Comet技术,即长轮询(Long Polling)和HTTP流,以实现在Web应用中...

    tomcat实现comet例子 comet tomcat 随机数

    tomcat实现comet例子,实现后台产生每隔几秒产生随机数,前台不刷新显示。tomcat实现comet例子,实现后台产生每隔几秒产生随机数,前台不刷新显示。tomcat实现comet例子,实现后台产生每隔几秒产生随机数,前台不...

    comet套件(comet4j-tomcat6/7.jar、comet4j.js)

    1. `comet4j-tomcat6.jar` 和 `comet4j-tomcat7.jar`:这两个JAR文件是Comet4J为Tomcat 6和Tomcat 7优化的版本,它们提供了与Tomcat容器集成的能力,允许开发者在Tomcat环境下使用Comet4J实现服务器推送功能。...

    comet4j-tomcat7后台信息推送jar包

    Comet4j是一个Java库,专门用于在服务器端与客户端之间进行实时的、双向的数据通信。这个技术在Web开发中非常有用,特别是当需要实时更新客户端(如浏览器)信息时,比如聊天应用、股票报价或者在线游戏。在这个场景...

    comet4j所需js与jar包(tomcat6与tomcat7)

    标题中的"comet4j所需js与jar包(tomcat6与tomcat7)"表明,这个压缩包包含了Comet4J框架在Tomcat 6和Tomcat 7这两种版本的应用服务器上运行所需的JavaScript文件和Java类库。Tomcat是Apache软件基金会的一个开源...

    comet4j-tomcat6.jar|comet4j-tomcat7.jar下载_以及对Jfinal类以及Zcurd项目的支持

    Comet4j为针对java web项目的后台消息推送工具,支持后台主动往浏览器推送消息。附件rar包提供Comet4j基础资源包下载,适用于所有Comet4j项目,同时特别针对comet4j对Jfinal类以及Zcurd项目的支持做了一些注意事项...

Global site tag (gtag.js) - Google Analytics