Tomcat6 comet, IE浏览器不支持Streaming ajax的解决方法小记

IE只不支持Streaming的。 所以不能通过以下的代码来拿到comet的数据。

     if (request.readyState == 3) {
if (request.status == 200) {
var increaseText = request.responseText.substring(index);
document.getElementById("cmessage").innerHTML = increaseText;
document.getElementById("message").innerHTML = document.getElementById("message").innerHTML + increaseText;
index = request.responseText.length;
document.getElementById("status").innerHTML = document.getElementById("status").innerHTML + "connected....<br>";
} else{
alert("status is " + request.status);
}
}else if (request.readyState==4 && request.status == 200){
document.getElementById("status").innerHTML = document.getElementById("status").innerHTML + "connection rest, try to re-connect.<br>";
connectComet();
index=0;
}


但是我们可以通过iframe的方法,但是用iframe的话浏览器会显示烦人的进度条。 我们可以通过以下的代码来避免。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Comet demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="prototype.js"></script>
</head>
<body>
<div id="content">The server time will be shown here</div>

<script type="text/javascript">
var comet = {
connection : false,
iframediv : false,

initialize: function() {
if (navigator.appVersion.indexOf("MSIE") != -1) {

// For IE browsers
comet.connection = new ActiveXObject("htmlfile");
comet.connection.open();
comet.connection.write("<html>");
comet.connection.write("<script>document.domain = '"+document.domain+"'");
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='./backend.php'></iframe>";

} else if (navigator.appVersion.indexOf("KHTML") != -1) {

// for KHTML browsers
comet.connection = document.createElement('iframe');
comet.connection.setAttribute('id', 'comet_iframe');
comet.connection.setAttribute('src', './backend.php');
with (comet.connection.style) {
position = "absolute";
left = top = "-100px";
height = width = "1px";
visibility = "hidden";
}
document.body.appendChild(comet.connection);

} else {

// For other browser (Firefox...)
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', './backend.php');
comet.connection.appendChild(comet.iframediv);
document.body.appendChild(comet.connection);

}
},

// this function will be called from backend.php
printServerTime: function (time) {
$('content').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>

</body>
</html>


其次我们需要有自动连接的功能,当comet连接timeout时,

  window.onload = function() {
var iframe = $("fullResponse");
iframe.src = "reader.php";
iframe.onload = disconnected;
if (iframe.readyState) setTimeout("MS_checkiframe(), 500);
}

function disconnected() {
// do whatever we normally do when we detect a disconnect
$("fullResponse").src = "reader.php";
if ($("fullResponse").readyState) setTimeout("MS_checkiframe(), 500);
}

function MS_checkiframe() {
if ($("fullResponse").readyState=="complete") {
disconnected();
} else {
setTimeout("MS_checkiframe()", 500);
}
}


最后是Tomcat comet servlet。

import org.apache.catalina.CometEvent;
import org.apache.catalina.CometProcessor;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;

/**
* Created by IntelliJ IDEA.
* User: Denny
* Date: 2009-11-19
* Time: 11:42:30
* To change this template use File | Settings | File Templates.
*/
public class IECometServlet extends HttpServlet implements CometProcessor{

public static ArrayList<HttpServletResponse> connections =
new ArrayList<HttpServletResponse>();

public void init() throws ServletException {

}

public void destroy() {
connections.clear();

}

public void event(CometEvent event) throws IOException, ServletException {
HttpServletRequest request = event.getHttpServletRequest();
HttpServletResponse response = event.getHttpServletResponse();
if (event.getEventType() == CometEvent.EventType.BEGIN) {
event.setTimeout(Integer.MAX_VALUE);
System.out.println("Begin for session: " + request.getSession(true).getId());
PrintWriter writer = response.getWriter();
writer.println("<!doctype html public \"-//w3c//dtd html 4.0 transitional//en\">");
writer.println("<html><head><script type=\"text/javascript\">var comet = window.parent.comet;</script></head><body>");
writer.print("<script type=\"text/javascript\">");
writer.println("comet.printServerTime('Connection begin...');");
writer.print("</script>");
writer.flush();
synchronized (connections) {
connections.add(response);
}
} else if (event.getEventType() == CometEvent.EventType.ERROR) {
System.out.println("Error for session: " + request.getSession(true).getId());
synchronized(connections) {
connections.remove(response);
}
event.close();
} else if (event.getEventType() == CometEvent.EventType.END) {
System.out.println("End for session: " + request.getSession(true).getId());
synchronized(connections) {
connections.remove(response);
}
PrintWriter writer = response.getWriter();
writer.println("</body></html>");
event.close();
} else if (event.getEventType() == CometEvent.EventType.READ) {
InputStream is = request.getInputStream();
byte[] buf = new byte[512];
do {
System.out.println("Read for session: " + request.getSession(true).getId());
int n = is.read(buf); //can throw an IOException
if (n > 0) {
log("Read " + n + " bytes: " + new String(buf, 0, n)
+ " for session: " + request.getSession(true).getId());
} else if (n < 0) {
System.err.println("Impossible.");
return;
}
} while (is.available() > 0);
}
}
}


我们往response中写入javascript片段, 这段javascript会在iframe中执行,然后在parent window中显示出来。


参考:[url]http://ajaxpatterns.org/HTTP_Streaming#Detecting_a_disconnect[/url]
[url]http://www.zeitoun.net/articles/comet_and_php/start[/url]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值