After carefully read the code of test unit: TestCometProcessor.java and the document,
it looks like that the CometEvent END is not always fired.
for example: a case that will not fire END event:
a http GET request, in the BEGIN event, the event.close() is invoked.
Please see the attached testcase code to demo this.

from java doc of CometEvent.close()
/The servlet should perform any needed cleanup as if it had received//
//     * an END or ERROR event.//
/
on the other side, from CometEvent END doc,
/ * END - End may be called to end the processing of the request. Fields that have// // * been initialized in the begin method should be reset. After this event has// // * been processed, the request and response objects, as well as all their dependent// // * objects will be recycled and used to process other requests. End will also be// // * called when data is available and the end of file is reached on the request input//
//     *  (this usually indicates the client has pipelined a request).<br>//
/
so, from doc, it implies the END is not always fired. just under some implicit conditions, it will fired.
this is really obscure to me... (sorry if I missed some doc)

Thanks for your help!


On 07/13/2013 05:36 PM, Mark Thomas wrote:
On 13/07/2013 02:23, stzdzyhs wrote:
Hello,
a basic CometProcessor servlet, I found that the CometEvent END is not
fired.only BEGIN event is fired.
There is a unit test that checks this. That suggests that the problem is
with your application rather than with Tomcat. The users list is the
place to seek help until you have a demonstrable bug - ideally in the
form of a unit test.

(tested on 7.0.34 and the latest 7.0.42)

please use a browser to access the servlet

BWT, it seems that the org.apache.tomcat.dbcp.dbcp.BasicDataSource code
missing in the svn:tc7.0.x/trunk,
can you please have a check ?
No need to check. You won't find that code in Tomcat's svn, nor should
it be there. Again, ask on the users list if you need an explanation of
why (or you could look at the build.xml file).

Mark


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



package org.apache.catalina.comet;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

import javax.net.SocketFactory;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import junit.framework.Assert;

import org.apache.catalina.Context;
import org.apache.catalina.comet.CometEvent.EventType;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.TomcatBaseTest;
import org.junit.Test;


/*
 * test CometEvent END is not fired for HTTP GET
 * must set an environment var before running this testcase  
 *    export tomcat.test.protocol=org.apache.coyote.http11.Http11NioProtocol
 */
public class TestCometProcessor2 extends TomcatBaseTest {

    @Test // test http Get 
    public void testCometConnectorStopGet() throws Exception {

        if (!isCometSupported()) {
            log.info("This test is skipped, because this connector does not support Comet.");
            return;
        }

        // Setup Tomcat instance
        SimpleCometServlet servlet = new SimpleCometServlet();
        Tomcat tomcat = getTomcatInstance();
        Context root = tomcat.addContext("", TEMP_DIR);
        Tomcat.addServlet(root, "comet", servlet);
        root.addServletMapping("/", "comet");
        tomcat.start();

        // Create connection to Comet servlet
        final Socket socket = SocketFactory.getDefault().createSocket("localhost", getPort());
        socket.setSoTimeout(10000);

        final OutputStream os = socket.getOutputStream();
        String requestLine = "GET http://localhost:"; + getPort() + "/ HTTP/1.1\r\n";
        os.write(requestLine.getBytes());
        os.write("\r\n".getBytes());

        //PingWriterThread writeThread = new PingWriterThread(100, os);
        //writeThread.start();

        InputStream is = socket.getInputStream();
        ResponseReaderThread readThread = new ResponseReaderThread(is);
        readThread.start();

        // Allow the first couple of PING messages to be written
        Thread.sleep(3000);

        tomcat.getConnector().stop();

        int count = 0;
        // Wait for the read thread to stop
        while (readThread.isAlive() && count < 50) {
            Thread.sleep(100);
            count ++;
        }

        // Destroy the connector once the executor has sent the end event
        tomcat.getConnector().destroy();

        System.out.println(readThread.getResponse());
        
        String[] response = readThread.getResponse().split("\r\n");
        String lastMessage = "";
        String lastResponseLine = "";
        for (int i = response.length; --i >= 0;) {
            lastMessage = response[i];
            if (lastMessage.startsWith("Client:")) {
                break;
            }
        }
        for (int i = response.length; --i >= 0;) {
            lastResponseLine = response[i];
            if (lastResponseLine.length() > 0) {
                break;
            }
        }
        StringBuilder status = new StringBuilder();
        // Expected, but is not 100% reliable:
        // WriteThread exception: java.net.SocketException
        // ReaderThread exception: null
        // Last message: [Client: END]
        // Last response line: [0] (empty chunk)
        // Last comet event: [END]
        // END event occurred: [true]
        status.append("Status:");
        status.append("\nReaderThread exception: " + readThread.getException());
        status.append("\nLast message: [" + lastMessage + "]");
        status.append("\nLast response line: [" + lastResponseLine + "]");
        status.append("\nLast comet event: [" + servlet.getLastEvent() + "]");
        status.append("\nEND event occurred: [" + servlet.getEndEventOccurred() + "]");
        
        if(servlet.getEndEventOccurred()) {
        	System.out.println("OK, END event fired");
        } else {
        	Assert.assertTrue(1==0);
            //log.error(status);
        }
    }
    

    private boolean isCometSupported() {
        String protocol = getTomcatInstance().getConnector().getProtocolHandlerClassName();
        if (protocol.indexOf("Nio") == -1 && protocol.indexOf("Apr") == -1) {
            return false;
        } else {
            return true;
        }
    }

    private static class SimpleCometServlet extends HttpServlet implements CometProcessor {

        private static final long serialVersionUID = 1L;

        private volatile EventType lastEvent;

        private volatile boolean endEventOccurred = false;

        public EventType getLastEvent() {
            return lastEvent;
        }

        public boolean getEndEventOccurred() {
            return endEventOccurred;
        }

        @Override
        public void init() throws ServletException {
        }

        @Override
        public void event(CometEvent event) throws IOException, ServletException {

            HttpServletRequest request = event.getHttpServletRequest();
            HttpServletResponse response = event.getHttpServletResponse();

            HttpSession session = request.getSession(true);
            session.setMaxInactiveInterval(30);

            lastEvent = event.getEventType();

            if (event.getEventType() == EventType.BEGIN) {
                response.setContentType("text/plain");
                response.getWriter().print("BEGIN" + "\r\n");
                event.close();
            } else if (event.getEventType() == EventType.READ) {
                InputStream is = request.getInputStream();
                int count = 0;
                while (is.available() > 0) {
                    is.read();
                    count ++;
                }
                String msg = "READ: " + count + " bytes";
                response.getWriter().print("Client: " + msg + "\r\n");
            } else if (event.getEventType() == EventType.END) {
            	System.out.println("Event End!!!!!!!!!!!!!!!!!!!!!!!!!!!");
                endEventOccurred = true;
                String msg = "END";
                response.getWriter().print("Client: " + msg + "\r\n");
                event.close();
            } else { // CometEvent  ERROR
                response.getWriter().print(event.getEventSubType() + "\r\n");
                event.close();
            }
            response.getWriter().flush();
        }
    }
    
    private static class ResponseReaderThread extends Thread {

        private final InputStream is;
        private StringBuilder response = new StringBuilder();

        private volatile Exception e = null;

        public ResponseReaderThread(InputStream is) {
            this.is = is;
        }

        public Exception getException() {
            return e;
        }

        public String getResponse() {
            return response.toString();
        }

        @Override
        public void run() {
            try {
                int c = is.read();
                while (c > -1) {
                    response.append((char) c);
                    c = is.read();
                }
            } catch (Exception e) {
                this.e = e;
            }
        }
    }
}

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to