2011-01-30 10 views
0

私はCometProcessorインターフェイスを使用する単純なサーブレットを持っています。CometProcessor Endイベントループ

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ページでは、私は、サーブレットを起動するためにEclipseを使用してい

<%@ 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> 

です。
私は、 "テキスト"をサーバーに送り、同じテキストとCometEvent名でエコーを返すことを期待しています。
データをサーバーに送信すると、最初に "200 ReadyState = 3 BEGIN text"が表示されます。これは予想されるシナリオです。約25秒待つと、コンソール出力に「エラー:タイムアウト」が表示されます。エラーイベントは25秒ごとに発生するため、ブラウザでは「200 ReadyState = 3 BEGIN textERROR textERROR textERROR textERROR textERROR text」のように表示されます。ここで、「text」は入力テキストです。 5 textERRORは、5つのエラーイベントが発生したことを意味します。私はなぜこれらのtextERRORが現れたのか分かりません。主な質問は、エラーイベント(タイムアウト)が25秒ごとに発生する理由です。
ブラウザでクライアントを閉じると、End Eventsの無限ループが発生します。なぜ私はどちらか分からないのですか?そのようなループを防ぐ方法は?
TomcatバージョンはApache Tomcat/6.0.28(Ubuntu 10.10)です。
ありがとうございます。スタートとして

+0

エンドループがなぜ起こるのか誰も知りません。 GlassFishに移行しようとしています... – Sqeezer

答えて

1

、あなたがこのような要求のタイムアウトを設定し、

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

25秒は、おそらくデフォルトです。あなたはこれを確認するために応答の

エラーがそのように25秒ごと

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

あなたのコードは、「エラーテキスト」、ないtextERRORを送るに

、タイムアウトが発生した場合に送信され、最後に新しい行を追加します。

無限ループの理由は、イベントを閉じていないことです。 CometEventエラーまたはENDが呼び出されたときは、これが最も可能性が高いあなたの無限ループの原因

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

で、[静的] Event.CLOSE()を呼び出す必要があります。

documentationを読むと、あなたが抱えている問題のほとんどが説明されています。

+0

私はGlassFishの周りで彗星のサポートをしていました。そして、ええ、私はそこに "response.getWriter()。close()"を実行する必要があることを発見しました。 Tomcatでも同じことを試してみました。しかし、event.close()は間違いなく良いです。しかし、私はevent.close()が最終的にwriter.close()を呼び出したと思います。助けてくれてありがとう! – Sqeezer