CometProcessor Завершение цикла - PullRequest
1 голос
/ 30 января 2011

У меня есть простой сервлет, который использует интерфейс CometProcessor.

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 для запуска сервлета.
Я ожидаю, что отправлю «текст» на сервер и верну эхо с тем же текстом и именем CometEvent.
Когда я отправляю данные на сервер первым, я получаю «200 ReadyState = 3 BEGIN text». Это ожидаемый сценарий. Если я подожду около 25 секунд, я получу «Ошибка: ВРЕМЯ» в выводе консоли. И событие ошибки будет запускаться каждые 25 секунд, поэтому в браузере я вижу что-то вроде «200 ReadyState = 3 BEGIN textERROR textERROR textERROR textERROR textERROR text», где «text» - это текст на входе. 5 textERRORs означает, что произошло 5 ошибок. Я не знаю, почему появились эти текстовые ОШИБКИ. И главный вопрос: почему событие ошибки (тайм-аут) срабатывает каждые 25 секунд?
Если я закрою клиент в браузере, я получу бесконечный цикл End Events. Почему это происходит, я тоже не знаю? Как предотвратить такую ​​петлю?
Версия Tomcat - Apache Tomcat / 6.0.28 для Ubuntu 10.10
Заранее спасибо.

1 Ответ

2 голосов
/ 03 февраля 2011

Для начала вы устанавливаете тайм-аут запроса следующим образом:

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

25 секунд, вероятно, по умолчанию.

Ошибка отправляется при возникновении тайм-аута, поэтому каждые 25секунд

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

в вашем коде отправляет «ОШИБКА текста», а не textERROR, добавьте новую строку в конце вашего ответа, чтобы проверить это.

Причина вашего бесконечного цикла,это вы не закрываете мероприятие.Когда вызывается CometEvent ERROR или END, вы должны вызывать event.close (),

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

Это, скорее всего, причина вашего бесконечного цикла.

Идите, прочитайте документацию , это объясняет большинство проблем, с которыми вы сталкиваетесь.

...