2011-01-30 36 views
0

我有一個使用CometProcessor接口的簡單servlet。CometProcessor End Event循環

package cc.co.sqeezer; 

import java.io.IOException; 

public class TestServlet extends HttpServlet implements CometProcessor { 
private static final long serialVersionUID = 1L; 

    public TestServlet() { 
     super(); 
    } 

    public void event(CometEvent event) { 
    if (event.getEventType() == CometEvent.EventType.BEGIN) 
    { 
     System.out.println("Begin"); 
     event.getHttpServletRequest().setAttribute("org.apache.tomcat.comet.timeout", new Integer(0xFFFFFFFF)); 
     send(event); 
    } 
    else if (event.getEventType() == CometEvent.EventType.READ) 
    { 
     System.out.println("Read"); 
     send(event); 
    } 
    else if (event.getEventType() == CometEvent.EventType.END) 
    { 
     System.out.println("End: " + event.getEventSubType()); 
     send(event); 
    } 
    else if (event.getEventType() == CometEvent.EventType.ERROR) 
    { 
     System.out.println("Error: " + event.getEventSubType()); 
     send(event); 
    } 

    } 

private void send(CometEvent event) { 
    HttpServletResponse response = event.getHttpServletResponse(); 
    response.setHeader("Pragma", "no-cache"); 
    response.setHeader("Cache-Control", "must-revalidate"); 
    response.setHeader("Cache-Control", "no-cache"); 
    response.setHeader("Cache-Control", "no-store"); 
    response.setDateHeader("Expires", 0); 

    String eventType = event.getEventType().toString(); 
    String receivedText = (String) event.getHttpServletRequest().getParameter("mytext"); 
    try { 
    response.getWriter().write(eventType + " " + receivedText); 
    response.getWriter().flush(); 
    } catch (IOException e) { 
    e.printStackTrace(); 
    } 
} 

public void init(ServletConfig config) throws ServletException { 
} 

} 

連接器是

<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" 
      connectionTimeout="20000" 
      URIEncoding="UTF-8" 
      redirectPort="8443" /> 

JSP頁面

<%@ page language="java" contentType="text/html; charset=UTF-8" 
    pageEncoding="UTF-8"%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>Test</title> 
</head> 
<body> 
<script type="text/javascript"><!-- 

function createRequestObject() { 
    if (typeof XMLHttpRequest === 'undefined') { 
    XMLHttpRequest = function() { 
     try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } 
     catch(e) {} 
     try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } 
     catch(e) {} 
     try { return new ActiveXObject("Msxml2.XMLHTTP"); } 
     catch(e) {} 
     try { return new ActiveXObject("Microsoft.XMLHTTP"); } 
     catch(e) {} 
     throw new Error("This browser does not support XMLHttpRequest."); 
    }; 
    } 
    return new XMLHttpRequest(); 
} 

var req = createRequestObject(); 


function sendData() 
{ 


    if (req) {  
     req.open("POST", "TestServlet", true); 
     req.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"); 
     req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 
     var params = "mytext=" + document.getElementById("mytext").value; 
     //req.setRequestHeader("Content-length", params.length); 

     req.onreadystatechange = processReqChange; 
     req.send(params); 
    } 
} 

function processReqChange() 
{ 
    try 
    { 
     if (req.readyState == 4) { 
      alert(req.status + " ReadyState=4 " + req.responseText); 
     } 
     if (req.readyState == 3) { 
     alert(req.status + " ReadyState=3 " + req.responseText); 
     } 
     if (req.readyState == 2) { 
      alert(req.status + " ReadyState=2 " + req.responseText); 
     } 
     if (req.readyState == 1) { 
     alert(req.status + " ReadyState=1 " + req.responseText); 
     } 
    } 
    catch(e) { 
     //alert("Error: " + e.description); 
    } 

} 

--></script> 
<input id="mytext" type="text"></input> 
<input type="button" value="send" onclick="sendData()"></input> 
</body> 
</html> 

我使用Eclipse來啓動該servlet。
我期望的是將「文本」發送到服務器並獲取具有相同文本和CometEvent名稱的回顯。
當我將數據發送到服務器時,首先獲得「200 ReadyState = 3 BEGIN文本」。這是預期的情況。如果我等待大約25秒,我會在控制檯輸出中看到「錯誤:超時」。並且錯誤事件每25秒會觸發一次,所以在瀏覽器中,我看到類似「200 ReadyState = 3 BEGIN textERROR textERROR textERROR textERROR textERROR text」的情況,其中「text」是輸入文本。 5個文本錯誤表示發生了5個錯誤事件。我不知道爲什麼會出現這些文字錯誤。主要問題是爲什麼錯誤事件(超時)每25秒觸發一次?
如果我在瀏覽器中關閉客戶端,我會得到一個無限循環的結束事件。爲什麼發生這種情況我也不知道?如何防止這種循環?
Tomcat版本是Ubuntu 10.10上的Apache Tomcat/6.0.28
預先感謝您。

+0

似乎沒有人知道爲什麼會發生這種結束循環。試圖遷移到GlassFish ... – Sqeezer 2011-02-02 19:28:02

回答

1

作爲開始,你這樣設置請求超時,

if (event.getEventType() == CometEvent.EventType.BEGIN) { 
    event.setTimeout(60 * 1000); 
    ... 
} 
... 

25秒可能是默認的。當發生超時

錯誤發送,所以每25秒

response.getWriter().write(eventType + " " + receivedText); 

在你的代碼發送「錯誤文本」,而不是textERROR,新行添加到末尾的您迴應驗證這一點。

你無限循環的原因是你沒有關閉事件。當CometEvent錯誤或END被調用時,您必須調用event.close(),

else if (event.getEventType() == CometEvent.EventType.END){ 
    event.close(); 
.... 

這很可能是您的無限循環的原因。

請閱讀documentation,它解釋了您遇到的大多數問題。

+0

我在彗星支持周圍玩GlassFish。是的,我發現那裏我應該做「response.getWriter()。close()」。我在Tomcat中也一樣,它的工作原理!但是event.close()肯定更好。但我認爲event.close()最終會調用writer.close()。非常感謝您的幫助! – Sqeezer 2011-02-03 20:57:34