CometProcessor 结束事件循环

发布于 2024-10-15 01:07:19 字数 4776 浏览 5 评论 0原文

我有一个使用 CometProcessor 接口的简单 servlet。

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 text”。这是预期的情况。如果我等待大约 25 秒,我将在控制台输出中收到“Error: TIMEOUT”。错误事件将每 25 秒触发一次,因此在浏览器中我看到类似“200 ReadyState=3 BEGIN textERROR textERROR textERROR textERROR textERROR text”的内容,其中“text”是输入中的文本。 5 textERRORs 表示发生了 5 个错误事件。我不知道为什么会出现这些文本错误。主要问题是为什么错误事件(超时)每 25 秒触发一次?
如果我在浏览器中关闭客户端,我将得到结束事件的无限循环。为什么会出现这样的情况我也不知道?如何防止这种循环?
Ubuntu 10.10 上的 Tomcat 版本为 Apache Tomcat/6.0.28
预先感谢您。

I have a simple servlet which uses CometProcessor interface.

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 is

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

Jsp page is

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

I'm using Eclipse to start the servlet.
What I would expect is to send "text" to the server and get back the echo with the same text and CometEvent name.
When I'm sending the data to the server the first I get "200 ReadyState=3 BEGIN text". This is expected scenario. If I wait for about 25 seconds I will get "Error: TIMEOUT" in console output. And error event will be fired every 25 seconds, so in browser I see something like "200 ReadyState=3 BEGIN textERROR textERROR textERROR textERROR textERROR text", where the "text" is the text in input. 5 textERRORs means that 5 error events occured. I don't know why these textERRORs appeared. And the main question is why the error event (timeout) fired every 25 seconds?
If I close client in browser I will get an infinite loop of End Events. Why this happens I don't know either? How to prevent that kind of loop?
Tomcat version is Apache Tomcat/6.0.28 on Ubuntu 10.10
Thank you in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

北风几吹夏 2024-10-22 01:07:19

首先,您像这样设置请求的超时,

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

25 秒可能是默认值。

发生超时时会发送错误,因此

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

代码中每 25 秒发送一次“ERROR text”,而不是 textERROR,请在响应末尾添加一个新行以验证这一点。

无限循环的原因是您没有关闭事件。当调用 CometEvent ERROR 或 END 时,您必须调用 event.close(),

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

这很可能是无限循环的原因。

去阅读文档,它解释了您遇到的大部分问题。

As a start, you set the timeout of the request like this,

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

25 seconds is probably the default.

Error is sent when a timeout occurs, so every 25 seconds

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

in your code sends the "ERROR text", not textERROR, add a new line to the end of you response to verify this.

The reason for your infinite loop, is you are not closing the event. When CometEvent ERROR or END is called, you must call event.close(),

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

This is most likely the cause of your infinite loop.

Go read the documentation, it explains most of the problems you are having.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文