我目前正在编写一个Comet应用程序,该应用程序要求我在持久连接上一次发送大块数据。但是,我在关闭连接之前无法刷新消息到客户端。是否有任何原因导致PrintWriter.flush()方法的行为不像我想的那样?
这是我的Tomcat Comet实现:
public void event(CometEvent event) throws IOException, ServletException {
HttpServletRequest request = event.getHttpServletRequest();
HttpServletResponse response = event.getHttpServletResponse();
if (event.getEventType() == EventType.BEGIN) {
request.setAttribute("org.apache.tomcat.comet.timeout", 300 * 1000);
PrintWriter out = response.getWriter();
out.println("BEGIN!");
out.flush();
System.out.println("EventType.BEGIN");
} else if (event.getEventType() == EventType.READ) {
InputStream is = request.getInputStream();
byte[] buf = new byte[512];
do {
int n = is.read(buf); //can throw an IOException
if (n > 0) {
System.out.println("Read " + n + " bytes: " + new String(buf, 0, n)
+ " for session: " + request.getSession(true).getId());
} else if (n < 0) {
return;
}
} while (is.available() > 0);
System.out.println("subtype: "+event.getEventSubType());
System.out.println("EventType.READ");
} else if (event.getEventType() == EventType.END) {
PrintWriter out = response.getWriter();
out.println("END!");
out.close();
System.out.println("checkError: "+out.checkError());
System.out.println(event.getEventSubType());
System.out.println("EventType.END");
//eventWorker.enqueue(new EndEvent(request, response));
} else if (event.getEventType() == EventType.ERROR) {
PrintWriter out = response.getWriter();
out.println("ERROR!");
out.flush();
System.out.println("checkError: "+out.checkError());
System.out.println("subtype: "+event.getEventSubType());
//response.getWriter().close();
System.out.println("EventType.ERROR");
} else {
(new ServletException("EXCEPTION")).printStackTrace();
}
}
因此,我在这里尝试发送消息“开始!”然后保持连接打开,这样我就可以发送更多数据。但是,似乎该消息只有在关闭连接后才能通过。
这是我的ajax代码:
$ .post('comet',function(data){alert(data);});
运行此代码后,Firebug告诉我这是响应标头:
伺服器:Apache-Coyote / 1.1
传输编码:分块
日期:2009年7月13日星期一21:16:29 GMT
这使我认为我的浏览器收到了一些数据,但是如何在关闭连接之前更新页面上的某些内容?
最佳答案
因此,似乎浏览器一直都在接收数据,但是由于未关闭连接,因此JavaScript认为数据仍在发送。这就是为什么我的jQuery回调函数没有被调用的原因。
在查看W3C AJAX教程时,我注意到XMLHttpRequest对象有不同的就绪状态。
var xmlhttp;
if (window.XMLHttpRequest)
{
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
else
{
alert("Your browser does not support XMLHTTP!");
}
xmlhttp.onreadystatechange=function()
{
if(xmlhttp.readyState==3) {
alert('process '+xmlhttp.responseText);
}
if(xmlhttp.readyState==4) {
alert('ready '+xmlhttp.responseText);
}
}
xmlhttp.open("GET","comet",true);
xmlhttp.send(null);
传统上,人们只处理第四个readyState,这意味着传输已完成。但是,就我而言,我需要在传输结束之前读取数据。因此,我需要代码来处理第三个readyState。
关于java - Java Servlet:为什么不刷新PrintWriter.flush()?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1122133/