加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – Apache Tomcat简单Comet Servlet

发布时间:2020-12-15 02:29:01 所属栏目:Java 来源:网络整理
导读:我正在尝试创建非常简单的Comet Servlet,它会将Hello World消息推送给订阅者: @WebServlet("/ChatServlet")public class ChatServlet extends HttpServlet implements CometProcessor { private static final long serialVersionUID = 1L; private MessageS
我正在尝试创建非常简单的Comet Servlet,它会将Hello World消息推送给订阅者:

@WebServlet("/ChatServlet")
public class ChatServlet extends HttpServlet implements CometProcessor {
    private static final long serialVersionUID = 1L;

    private MessageSender messageSender = null;
    private static final Integer TIMEOUT = 60 * 1000;    

    public void init(ServletConfig config) throws ServletException {
          messageSender = new MessageSender();
            Thread messageSenderThread =
                    new Thread(messageSender);
            messageSenderThread.setDaemon(true);
            messageSenderThread.start();
        }

    public void destroy() {
     //   messageSender.stop();
        messageSender = null;
        }

    @Override
    public void event(CometEvent event) throws IOException,ServletException {
        HttpServletRequest request = event.getHttpServletRequest();
        HttpServletResponse response = event.getHttpServletResponse();
        if (event.getEventType() == CometEvent.EventType.BEGIN) {
            request.setAttribute("org.apache.tomcat.comet.timeout",TIMEOUT);
            System.out.println("Begin for session: " + request.getSession(true).getId());
            messageSender.setConnection(response);
        }
        else if (event.getEventType() == CometEvent.EventType.ERROR) {
            System.out.println("Error for session: " + request.getSession(true).getId());
            event.close();
        } else if (event.getEventType() == CometEvent.EventType.END) {
            System.out.println("End for session: " + request.getSession(true).getId());
            event.close();
        } else if (event.getEventType() == CometEvent.EventType.READ) {
            throw new UnsupportedOperationException("This servlet does not accept data");
    }
    }
}

然后我的Runnable看起来像这样:

public class MessageSender implements Runnable {

       protected boolean running = true;
        protected final List<String> messages = new ArrayList<String>();
        private ServletResponse connection;

        public synchronized void setConnection(ServletResponse connection){
            this.connection = connection;
            notify();
        }

    @Override
    public void run() {
         while (running) {
             if (messages.size() == 0) {
                    try {
                        synchronized (messages) {
                            messages.wait();
                        }
                    } catch (InterruptedException e) {
                        // Ignore
                    } 
         }
         String[] pendingMessages = null;
          synchronized (messages) {
              pendingMessages = messages.toArray(new String[0]);
              messages.clear();
          }
          try {
              if (connection == null){
                  try{
                      synchronized(this){
                          wait();
                      }
                  } catch (InterruptedException e){
                      // Ignore
                  }
              }
              PrintWriter writer = connection.getWriter();

                  writer.println("hello World");
                  System.out.println("Writing Hello World");                  
              writer.flush();
              writer.close();
              connection = null;
              System.out.println("Closing connection");
          } catch (IOException e) {
              System.out.println("IOExeption sending message"+e.getMessage());
          }
         }
    }
}

现在我的Dojo cometd代码如下所示:

<script src="dojo/dojo.js"></script>    
    <script type="text/javascript">
    dojo.require("dojox.cometd");

    dojo.addOnLoad(function(){
        dojox.cometd.init("ChatServlet");
        dojox.cometd.subscribe("ChatServlet",window,"alertMessage");
    });

    function alertMessage(message) {
        alert("Message: " + message);
    }

    </script>

现在当我加载客户端时,我收到以下错误:

Begin for session: C898A372F1B1199C04CA308F715ABC36Nov 6,2011 2:00:48 PM org.apache.catalina.core.StandardWrapperValve event
SEVERE: Servlet.service() for servlet [com.vanilla.servlet.ChatServlet] in context with path [/Servlet3Comet] threw exception
java.lang.UnsupportedOperationException: This servlet does not accept data
    at com.vanilla.servlet.ChatServlet.event(ChatServlet.java:75)

Error for session: C898A372F1B1199C04CA308F715ABC36
End for session: C898A372F1B1199C04CA308F715ABC36

我究竟做错了什么?
为什么cometD订阅会调用CometEvent.EventType.READ?
有人有任何工作彗星的例子吗?

P.S:我根据Tomcat配置切换到了Nio.

解决方法

init(ServletConfig)的文档:

public void init(ServletConfig config) throws ServletException Called
by the servlet container to indicate to a servlet that the servlet is
being placed into service.

See Servlet#init. This implementation stores the ServletConfig object
it receives from the servlet container for later use. When overriding
this form of the method,call super.init(config).

和init()的文档:

public void init() throws ServletException A convenience method which
can be overridden so that there’s no need to call super.init(config).

Instead of overriding init(ServletConfig),simply override this method
and it will be called by GenericServlet.init(ServletConfig config).
The ServletConfig object can still be retrieved via
getServletConfig().

当覆盖init(ServletConfig)时,你的第一个调用必须是super.init(config);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读