客户端接收代码:
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>
分享到:
相关推荐
comet4j消息推送所需的comet4j-tomcat7.jar包,comet4j-tomcat7.jar
服务器主动向客户端推送消息所需的comet4j-tomcat7.jar和comen4j.js,在此需注意:comet4j-tomcat7.jar目前仅支持tomcat6和tomcat7
comet4j-tomcat6,comet4j-tomcat7,comet4j.js,comet4j.js,以及一个样例
comet4j-tomcat6、comet4j-tomcat7 的jar包和comet4j.js资源下载
Comet4J(Comet for Java)是一个纯粹基于AJAX(XMLHTTPRequest)的服务器推送框架,消息以JSON方式传递,具备长轮询、长连接、自动选择三种工作模式 文件包含comet4j-tomcat6.jar , comet4j-tomcat7.jar , comet4j.js...
comet4j消息推送所需的comet4j.js文件、comet4j-tomcat6.jar、comet4j-tomcat7.jar包
压缩包中包含comet4j向客户端主动推送所需要的jar包和js(comet4j-tomcat6.jar、comet4j-tomcat7.jar、comet4j.js)
包含comet4j-tomcat6.jar,comet4j-tomcat7.jar,comet4j.js,以及官网demo:comet4j-tomcat6-demo.war
里面包含comet4j.js,comet4j-tomcat6.jar,comet4j-tomcat7.jar,comet4j开发指南等资源
tomcat实现comet例子,实现后台产生每隔几秒产生随机数,前台不刷新显示。tomcat实现comet例子,实现后台产生每隔几秒产生随机数,前台不刷新显示。tomcat实现comet例子,实现后台产生每隔几秒产生随机数,前台不...
comet4j+tomcat6+tomcat7并附完整版Demo,解决java后端向去前台推送信息的问题
使用comet4j功能所必需的js文件以及jar包资源(comet4j-tomcat7)
comet4j+tomcat7 简单demo,内含源代码与操作手册,可直接部署后使用
tomcat7后台服务器,java项目实现后台推送信息到客户端浏览器
Comet4j为针对java web项目的后台消息推送工具,支持后台主动往浏览器推送消息。附件rar包提供Comet4j基础资源包下载,适用于所有Comet4j项目,同时特别针对comet4j对Jfinal类以及Zcurd项目的支持做了一些注意事项...
Comet4J是一个微型的即时推送框架,它分为服务端与客户端两部分,你只要将服务器端(JAR文件,目前仅支持Tomcat6、7)放入WEB-INF\lib,客户端(JavaScript文件)引入到页面,那么你的应用就具备了向客户端推送信息的...
供研究comet4j---服务器主动向客户端推送消息
comet4j消息推送所需js与jar包(tomcat6与tomcat7) Comet4J(Comet for Java)是一个纯粹基于AJAX(XMLHTTPRequest)的服务器推送框架