Apache Tomcat Simple Comet Servlet

I am trying to create a very simple Comet Servlet that will push Hello World subscribers a message:

@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"); } } } 

and then my runnable looks like this:

 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()); } } } } 

now my cometd Dojo code is as follows:

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

Now, when I download the client, I get the following error:

 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 

What am I doing wrong? Why does cometD subscription call CometEvent.EventType.READ ? Does anyone have a working example of a comet?

PS: I switched to Nio according to the configuration of Tomcat.

+4
source share
1 answer

Documentation for init(ServletConfig) :

public void init(ServletConfig config) throws ServletException by the servlet container to indicate to the servlet that the servlet is being commissioned.

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

And Documentation for init ():

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

Instead of overriding init (ServletConfig), just override this method and it will be called GenericServlet.init (ServletConfig config). The ServletConfig object can still be obtained through getServletConfig ().

When overriding init (ServletConfig), your first call should be super.init(config);

+1
source

Source: https://habr.com/ru/post/1379883/


All Articles