You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Peter Warren <to...@gmail.com> on 2008/01/07 20:15:42 UTC

comet questions

I have some comet questions.  I'm using the tomcat 6.0.x trunk as of
last Friday.

1) My comet event timeout setting being honored.  How come?  I set the
timeout for 3 hours but a timeout event gets generated every 2
minutes.  If I inspect the comet event for which the timeout is
triggered, I see a setting for the request attribute of:
org.apache.tomcat.comet.timeout=10800000.

I set it as follows:

    public void event(CometEvent cometEvent) throws IOException,
ServletException {
	...
        if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
	    // COMET_TIMEOUT = 3 * 60 * 60 * 1000
            cometEvent.setTimeout(TimingConstants.COMET_TIMEOUT);

Do I need to set something else as well?

2) Occasionally I'm getting a comet event of type ERROR without any
subtype (i.e. not TIMEOUT, CLIENT_DISCONNECT, etc.).  What does that
indicate?  I don't see any errors in my catalina log.

3) Reading the response from a comet servlet fails for one of my
client machines.  I wrote a simple test to check the problem.  This
test succeeds for many other users.  For the failing client, the
client request is received by the comet servlet, and the servlet's
response is written and flushed to the stream.  The client then simply
waits indefinitely trying to read the response.  The failing client is
a Windows XP machine.  Could anyone shed some light on why this might
be happening, or give me some clues as to how to debug?  Could it be a
firewall issue on the client end, a router issue on my end?

The test is currently up at: http://www.seekspeak.com/test.html.  It
tests: a http connection to a normal servlet, then a comet connection
to a comet servlet using httpurlconnection, then a comet connection to
a comet servlet using a socket.  For the failing client, both comet
tests fail.

Below is some of the test code for the raw socket test.

Thanks for any help!

Peter

CLIENT
------
    private void testCometConnection() throws IOException {
	...
        URL url = new URL("http://www.seekspeak.com/CometTest");
        channel = new CometChannel(url);
        Thread testThread = new Thread() {
            public void run() {
                try {
                    channel.send("test");
                    String received = channel.receive();
                    ...
                    }
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        };
        testThread.start();
	...
    }

    private class CometChannel {

        private static final int INPUT_BUFFER_SIZE = 512;

        private static final int OUTPUT_BUFFER_SIZE = 512;

        private static final String DELIMITER = "\r\n";

        private URL url;

        private BufferedReader inputReader;

        private PrintWriter outputWriter;

        private Socket socket;

        public CometChannel(URL url) throws IOException {
            this.url = url;
            initConnection();
        }

        private void initSocket() throws IOException {
            int port = url.getPort();
            port = (port < 0) ? url.getDefaultPort() : port;
            try {
                socket = new Socket(url.getHost(), port);
                socket.setKeepAlive(true);
                inputReader = new BufferedReader(new
InputStreamReader(socket.getInputStream()), INPUT_BUFFER_SIZE);
                outputWriter = new PrintWriter(new BufferedWriter(new
OutputStreamWriter(socket.getOutputStream()),
                        OUTPUT_BUFFER_SIZE));
            } catch (NoRouteToHostException nrthe) {
                System.out.println("host: " + url.getHost());
                nrthe.printStackTrace();
            }
        }

        private void initConnection() throws IOException {
            initSocket();
            sendHeaders();
        }

        private void sendHeaders() {
            String path = url.getPath();
            StringBuffer outputBuffer = new StringBuffer();
            outputBuffer.append("POST " + path + " HTTP/1.1" + DELIMITER);
            outputBuffer.append("Host: " + url.getHost() + DELIMITER);
            outputBuffer.append("User-Agent: CometTestApplet" + DELIMITER);
            outputBuffer.append("Connection: keep-alive" + DELIMITER);
            outputBuffer.append("Content-Type: text/plain" + DELIMITER);
            outputBuffer.append("Transfer-Encoding: chunked" + DELIMITER);
            outputBuffer.append(DELIMITER);
            synchronized (outputWriter) {
                outputWriter.print(outputBuffer.toString());
            }
        }

        public void send(String chunkData) throws IOException {
            // chunk length field in hex
            String hexChunkLength = Integer.toHexString(chunkData.length());

            StringBuffer outputBuffer = new StringBuffer();
            outputBuffer.append(hexChunkLength);
            outputBuffer.append(DELIMITER);
            outputBuffer.append(chunkData);
            outputBuffer.append(DELIMITER);
            synchronized (outputWriter) {
                outputWriter.print(outputBuffer.toString());
                outputWriter.flush();
            }
        }

        private String readChunk() throws IOException {
            StringBuffer inputBuffer = new StringBuffer();
            String hexChunkSize = inputReader.readLine();
            if (hexChunkSize != null) {
                int chunkSize = Integer.parseInt(hexChunkSize, 16);
                int charsRead = 0;

                char[] buf = new char[chunkSize];
                do {
                    int n = inputReader.read(buf);
                    charsRead += n;
                    if (n > 0) {
                        inputBuffer.append(new String(buf, 0, n));
                    } else if (n < 0) {
                        // occurs when connection is closed, often in response
                        // to http session timeout from server
                        throw new IOException("no bytes read");
                    }
                } while (charsRead < chunkSize);
                // extra \r\n sent after chunk - part of protocol
                inputReader.readLine();
            }
            return inputBuffer.toString();
        }

        public String receive() throws IOException {
            readHeaders();
            return readChunk();
        }

        private void readHeaders() throws IOException {
            String header;
            while ((header = inputReader.readLine()) != null) {
                System.out.println("header: " + header);
                if (header.length() == 0) {
                    break;
                }
            }
        }
	...
    }

SERVER
------
public class CometTestServlet extends HttpServlet implements CometProcessor {
    private static final long serialVersionUID = 5472498184127924791L;

    public void event(CometEvent cometEvent) throws IOException,
ServletException {
        HttpServletRequest request = cometEvent.getHttpServletRequest();
        HttpSession httpSession = request.getSession(true);
        if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
            cometEvent.setTimeout(3 * 60 * 60 * 1000); // 3 hours
            // tell the http session not to timeout - will invalidate it on
            // error or end
            httpSession.setMaxInactiveInterval(-1);
        } else if (cometEvent.getEventType() == CometEvent.EventType.ERROR) {
            handleErrorEvent(cometEvent, httpSession);
        } else if (cometEvent.getEventType() == CometEvent.EventType.END) {
            close(cometEvent, httpSession);
        } else if (cometEvent.getEventType() == CometEvent.EventType.READ) {
            handleReadEvent(cometEvent);
        }
    }

    protected void handleErrorEvent(CometEvent cometEvent, HttpSession
httpSession) throws IOException {
        if (cometEvent.getEventSubType() != CometEvent.EventSubType.TIMEOUT) {
            close(cometEvent, httpSession);
        }
    }

    private void close(CometEvent cometEvent, HttpSession httpSession)
throws IOException {
        cometEvent.close();
        httpSession.invalidate();
    }

    private void handleReadEvent(CometEvent cometEvent) throws
IOException, ServletException {
        ServerCometChannel talker = new ServerCometChannel(cometEvent);
        respond(talker);
    }

    private void respond(ServerCometChannel channel) throws IOException {
        String clientMessage = channel.receive();

        if (clientMessage != null && clientMessage.length() > 0) {
            channel.send("comet succeeded");
        }
    }

    private class ServerCometChannel {

        private static final int OUTPUT_BUFFER_SIZE = 512;

        private CometEvent cometEvent;

        private InputStream inputStream;

        private PrintWriter outputWriter;

        public ServerCometChannel(CometEvent cometEvent) throws
IOException, ServletException {
            this.cometEvent = cometEvent;
            inputStream = cometEvent.getHttpServletRequest().getInputStream();
            OutputStream outputStream =
cometEvent.getHttpServletResponse().getOutputStream();
            this.outputWriter = new PrintWriter(new BufferedWriter(new
OutputStreamWriter(outputStream),
                    OUTPUT_BUFFER_SIZE));
        }

        private String receive() throws IOException {
            StringBuffer buffer = new StringBuffer();
            byte[] buf = new byte[512];
            while (inputStream.available() > 0) {
                int n = inputStream.read(buf);
                if (n > 0) {
                    buffer.append(new String(buf, 0, n));
                }
            }
            return buffer.toString();
        }

        public void send(String msg) {
            synchronized (cometEvent.getHttpServletResponse()) {
                outputWriter.print(msg);
                outputWriter.flush();
            }
        }

        public void close() throws IOException {
            inputStream.close();
            outputWriter.close();
        }
    }

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: comet questions

Posted by Filip Hanik - Dev Lists <de...@hanik.com>.
setting a timeout doesn't mean you're gonna get a timeout in exactly 5 
seconds, it means that after 5 seconds the server can time it out.
the server is still only checking for timeouts at certain intervals.

the way you describe it, like connectionTimeout drives your timeout, 
that would mean you're actually in an event, what I think it is, it 
could be related to chunk parsing, and that will be taken care of in the 
next release, hopefully out next week


filip

Peter Warren wrote:
> Anyone else experiencing comet timeout problems with the nio connector
> and the latest 6.0.x trunk?
>
> My cometEvent.setTimeout(...) setting is ignored, but I do receive
> comet timeouts based on the connectionTimeout setting for the nio
> connector.  Setting the connectionTimeout to 10 secs gives me a comet
> timeout event every 10 secs.  Setting it to 2 mins gives a comet
> timeout every 2 mins.
>
> The docs don't mention any link between the connectionTimeout settings
> and comet timeout events that I can find.
>
> Connector config:
>     <Connector port="80"
> protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="500"
> connectionTimeout="10000" keepAliveTimeout="30000"
> maxKeepAliveRequests="-1" socket.soKeepAlive="true"
> socket.appReadBufSize="2048" socket.appWriteBufSize="2048"
> socket.rxBufSize="2048" socket.txBufSize="2048"
> acceptorThreadCount="2" redirectPort="8443" />
>
> On Jan 9, 2008 12:23 PM, Peter Warren <to...@gmail.com> wrote:
>   
>> Using the nio connector from the latest 6.0.x trunk, I'm failing to
>> receive any comet timeouts.  I set the comet timeout to 5 secs but,
>> after waiting much longer than 5 secs, the only two events I receive
>> are begin and read.
>>
>> event: BEGIN, subtype: null
>>         for servlet: com.seekspeak.server.debug.CometTestServlet
>>         time: Wed Jan 09 12:12:28 PST 2008
>>         on cometEvent: org.apache.catalina.connector.CometEventImpl@1b3278a
>>         with "org.apache.tomcat.comet.timeout" attribute: null
>>         with "org.apache.tomcat.comet.timeout.support" attribute: true
>> event: READ, subtype: null
>>         for servlet: com.seekspeak.server.debug.CometTestServlet
>>         time: Wed Jan 09 12:12:28 PST 2008
>>         on cometEvent: org.apache.catalina.connector.CometEventImpl@1b3278a
>>         with "org.apache.tomcat.comet.timeout" attribute: 5000
>>         with "org.apache.tomcat.comet.timeout.support" attribute: true
>>
>> I see that the Http11NioProcessor changed some comet timeout specific
>> code from the previous rev.  Could this be having an impact?
>>
>> Below is my test client and test servlet.  Am I doing something wrong?
>>
>> Thanks,
>> Peter
>>
>> SERVLET
>> ---------------
>> public class CometTestServlet extends HttpServlet implements CometProcessor {
>>
>>     public void event(CometEvent cometEvent) throws IOException,
>> ServletException {
>>         System.out.println("event: " + cometEvent.getEventType() + ",
>> subtype: " + cometEvent.getEventSubType());
>>         System.out.println("\tfor servlet: " + this.getClass().getName());
>>         System.out.println("\ttime: " + new Date(System.currentTimeMillis()));
>>         System.out.println("\ton cometEvent: " + cometEvent);
>>         System.out.println("\twith \"org.apache.tomcat.comet.timeout\"
>> attribute: "
>>                 +
>> cometEvent.getHttpServletRequest().getAttribute("org.apache.tomcat.comet.timeout"));
>>         System.out.println("\twith
>> \"org.apache.tomcat.comet.timeout.support\" attribute: "
>>                 +
>> cometEvent.getHttpServletRequest().getAttribute("org.apache.tomcat.comet.timeout.support"));
>>         if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
>>             cometEvent.setTimeout(5 * 1000);
>>         } else if (cometEvent.getEventType() == CometEvent.EventType.ERROR) {
>>             cometEvent.close();
>>         } else if (cometEvent.getEventType() == CometEvent.EventType.END) {
>>             cometEvent.close();
>>         } else if (cometEvent.getEventType() == CometEvent.EventType.READ) {
>>             handleReadEvent(cometEvent);
>>         }
>>     }
>>
>>
>>     private void handleReadEvent(CometEvent cometEvent) throws
>> IOException, ServletException {
>>         ServerCometChannel talker = new ServerCometChannel(cometEvent);
>>         respond(talker);
>>     }
>>
>>     private void respond(ServerCometChannel channel) throws IOException {
>>         String clientMessage = channel.receive();
>>         if (clientMessage != null && clientMessage.length() > 0) {
>>             channel.send("comet succeeded");
>>         }
>>     }
>>
>>     private class ServerCometChannel {
>>
>>         private static final int OUTPUT_BUFFER_SIZE = 512;
>>
>>         private CometEvent cometEvent;
>>
>>         private InputStream inputStream;
>>
>>         private PrintWriter outputWriter;
>>
>>         public ServerCometChannel(CometEvent cometEvent) throws
>> IOException, ServletException {
>>             this.cometEvent = cometEvent;
>>             inputStream = cometEvent.getHttpServletRequest().getInputStream();
>>             OutputStream outputStream =
>> cometEvent.getHttpServletResponse().getOutputStream();
>>             this.outputWriter = new PrintWriter(new BufferedWriter(new
>> OutputStreamWriter(outputStream),
>>                     OUTPUT_BUFFER_SIZE));
>>         }
>>
>>         private String receive() throws IOException {
>>             StringBuffer buffer = new StringBuffer();
>>             byte[] buf = new byte[512];
>>             while (inputStream.available() > 0) {
>>                 int n = inputStream.read(buf);
>>                 if (n > 0) {
>>                     buffer.append(new String(buf, 0, n));
>>                 }
>>             }
>>             return buffer.toString();
>>         }
>>
>>         public void send(String msg) {
>>             synchronized (cometEvent.getHttpServletResponse()) {
>>                 outputWriter.print(msg);
>>                 outputWriter.flush();
>>                 try {
>>                     cometEvent.getHttpServletResponse().flushBuffer();
>>                 } catch (IOException ioe) {
>>                     ioe.printStackTrace();
>>                 }
>>             }
>>         }
>>     }
>> }
>>
>> CLIENT
>> ----------
>> public class CometTest {
>>
>>     public static void main(String[] args) throws Exception {
>>         CometTest test = new CometTest();
>>         test.test();
>>     }
>>
>>     private void test() throws Exception {
>>         URL url = new URL("http://www.seekspeak.com/CometTest");
>>         CometChannel channel = new CometChannel(url);
>>         channel.send("test");
>>         String received = channel.receive();
>>         System.out.println("received: " + received);
>>         Thread.sleep(60 * 60 * 1000);
>>     }
>>
>>     private class CometChannel {
>>
>>         private static final int INPUT_BUFFER_SIZE = 512;
>>
>>         private static final int OUTPUT_BUFFER_SIZE = 512;
>>
>>         private static final String DELIMITER = "\r\n";
>>
>>         private URL url;
>>
>>         private BufferedReader inputReader;
>>
>>         private PrintWriter outputWriter;
>>
>>         private Socket socket;
>>
>>         private boolean firstRead = true;
>>
>>
>>         public CometChannel(URL url) throws IOException {
>>             this.url = url;
>>             initConnection();
>>         }
>>
>>         private void initSocket() throws IOException {
>>             int port = url.getPort();
>>             port = (port < 0) ? url.getDefaultPort() : port;
>>             try {
>>                 socket = new Socket(url.getHost(), port);
>>                 socket.setKeepAlive(true);
>>                 inputReader = new BufferedReader(new
>> InputStreamReader(socket.getInputStream()), INPUT_BUFFER_SIZE);
>>                 outputWriter = new PrintWriter(new BufferedWriter(new
>> OutputStreamWriter(socket.getOutputStream()),
>>                         OUTPUT_BUFFER_SIZE));
>>             } catch (NoRouteToHostException nrthe) {
>>                 System.out.println("host: " + url.getHost());
>>                 nrthe.printStackTrace();
>>             }
>>         }
>>
>>         private void initConnection() throws IOException {
>>             initSocket();
>>             sendHeaders();
>>         }
>>
>>         private void sendHeaders() {
>>             String path = url.getPath();
>>             StringBuffer outputBuffer = new StringBuffer();
>>             outputBuffer.append("POST " + path + " HTTP/1.1" + DELIMITER);
>>             outputBuffer.append("Host: " + url.getHost() + DELIMITER);
>>             outputBuffer.append("User-Agent: CometTestApplet" + DELIMITER);
>>             outputBuffer.append("Connection: keep-alive" + DELIMITER);
>>             outputBuffer.append("Content-Type: text/plain" + DELIMITER);
>>             outputBuffer.append("Transfer-Encoding: chunked" + DELIMITER);
>>             outputBuffer.append(DELIMITER);
>>             synchronized (outputWriter) {
>>                 outputWriter.print(outputBuffer.toString());
>>             }
>>         }
>>
>>         public void send(String chunkData) throws IOException {
>>             String hexChunkLength = Integer.toHexString(chunkData.length());
>>
>>             StringBuffer outputBuffer = new StringBuffer();
>>             outputBuffer.append(hexChunkLength);
>>             outputBuffer.append(DELIMITER);
>>             outputBuffer.append(chunkData);
>>             outputBuffer.append(DELIMITER);
>>             synchronized (outputWriter) {
>>                 outputWriter.print(outputBuffer.toString());
>>                 outputWriter.flush();
>>             }
>>         }
>>
>>         private String readChunk() throws IOException {
>>             StringBuffer inputBuffer = new StringBuffer();
>>             String hexChunkSize = inputReader.readLine();
>>             System.out.println("chunk size: " + hexChunkSize);
>>             if (hexChunkSize != null) {
>>                 int chunkSize = Integer.parseInt(hexChunkSize, 16);
>>                 int charsRead = 0;
>>
>>                 char[] buf = new char[chunkSize];
>>                 do {
>>                     int n = inputReader.read(buf);
>>                     charsRead += n;
>>                     if (n > 0) {
>>                         inputBuffer.append(new String(buf, 0, n));
>>                     } else if (n < 0) {
>>                         // occurs when connection is closed, often in response
>>                         // to http session timeout from server
>>                         throw new IOException("no bytes read");
>>                     }
>>                 } while (charsRead < chunkSize);
>>                 // extra \r\n sent after chunk - part of protocol
>>                 inputReader.readLine();
>>             }
>>             return inputBuffer.toString();
>>         }
>>
>>         public String receive() throws IOException {
>>             if (firstRead) {
>>                 firstRead = false;
>>                 readHeaders();
>>             }
>>             return readChunk();
>>         }
>>
>>         private void readHeaders() throws IOException {
>>             String header;
>>             while ((header = inputReader.readLine()) != null) {
>>                 System.out.println("header: " + header);
>>                 if (header.length() == 0) {
>>                     break;
>>                 }
>>             }
>>         }
>>     }
>> }
>>
>>
>>
>> On Jan 7, 2008 4:43 PM, Filip Hanik - Dev Lists <de...@hanik.com> wrote:
>>     
>>> The time when it is called without a subtype, is if the
>>> application(servlet) has an unhandled exception
>>>
>>> in terms of timeout, that should work just dandy, unless the client
>>> disconnects, at which point at which point you might get a subtype of
>>> IOEXCEPTION, or CLIENT_DISCONNECT
>>> depending on the OS
>>>
>>> Filip
>>>
>>>
>>> Peter Warren wrote:
>>>       
>>>> Using the NIO connector: protocol="org.apache.coyote.http11.Http11NioProtocol".
>>>>
>>>> I'll add response.flushBuffer() and see if that helps.
>>>>
>>>> The tomcat version I was testing against was current with svn as of
>>>> last Friday.  I just updated and the only files that are new are:
>>>> catalina.policy
>>>> STATUS.txt
>>>> changelog.xml
>>>>
>>>> Any ideas about the timeout setting or the comet error event without a subtype?
>>>>
>>>> Thanks for your response!
>>>>
>>>> Peter
>>>>
>>>> On Jan 7, 2008 12:44 PM, Filip Hanik - Dev Lists <de...@hanik.com> wrote:
>>>>
>>>>         
>>>>> what connector are you using?
>>>>> I would try to use response.flushBuffer when you wanna flush it out (ie
>>>>> after you've written to and flushed your stream).
>>>>>
>>>>> also, there have been some bug fixes, that you can get from SVN, or wait
>>>>> for 6.0.16 to come out
>>>>>
>>>>> Filip
>>>>>
>>>>>
>>>>> Peter Warren wrote:
>>>>>
>>>>>           
>>>>>> I have some comet questions.  I'm using the tomcat 6.0.x trunk as of
>>>>>> last Friday.
>>>>>>
>>>>>> 1) My comet event timeout setting being honored.  How come?  I set the
>>>>>> timeout for 3 hours but a timeout event gets generated every 2
>>>>>> minutes.  If I inspect the comet event for which the timeout is
>>>>>> triggered, I see a setting for the request attribute of:
>>>>>> org.apache.tomcat.comet.timeout=10800000.
>>>>>>
>>>>>> I set it as follows:
>>>>>>
>>>>>>     public void event(CometEvent cometEvent) throws IOException,
>>>>>> ServletException {
>>>>>>       ...
>>>>>>         if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
>>>>>>           // COMET_TIMEOUT = 3 * 60 * 60 * 1000
>>>>>>             cometEvent.setTimeout(TimingConstants.COMET_TIMEOUT);
>>>>>>
>>>>>> Do I need to set something else as well?
>>>>>>
>>>>>> 2) Occasionally I'm getting a comet event of type ERROR without any
>>>>>> subtype (i.e. not TIMEOUT, CLIENT_DISCONNECT, etc.).  What does that
>>>>>> indicate?  I don't see any errors in my catalina log.
>>>>>>
>>>>>> 3) Reading the response from a comet servlet fails for one of my
>>>>>> client machines.  I wrote a simple test to check the problem.  This
>>>>>> test succeeds for many other users.  For the failing client, the
>>>>>> client request is received by the comet servlet, and the servlet's
>>>>>> response is written and flushed to the stream.  The client then simply
>>>>>> waits indefinitely trying to read the response.  The failing client is
>>>>>> a Windows XP machine.  Could anyone shed some light on why this might
>>>>>> be happening, or give me some clues as to how to debug?  Could it be a
>>>>>> firewall issue on the client end, a router issue on my end?
>>>>>>
>>>>>> The test is currently up at: http://www.seekspeak.com/test.html.  It
>>>>>> tests: a http connection to a normal servlet, then a comet connection
>>>>>> to a comet servlet using httpurlconnection, then a comet connection to
>>>>>> a comet servlet using a socket.  For the failing client, both comet
>>>>>> tests fail.
>>>>>>
>>>>>> Below is some of the test code for the raw socket test.
>>>>>>
>>>>>> Thanks for any help!
>>>>>>
>>>>>> Peter
>>>>>>
>>>>>> CLIENT
>>>>>> ------
>>>>>>     private void testCometConnection() throws IOException {
>>>>>>       ...
>>>>>>         URL url = new URL("http://www.seekspeak.com/CometTest");
>>>>>>         channel = new CometChannel(url);
>>>>>>         Thread testThread = new Thread() {
>>>>>>             public void run() {
>>>>>>                 try {
>>>>>>                     channel.send("test");
>>>>>>                     String received = channel.receive();
>>>>>>                     ...
>>>>>>                     }
>>>>>>                 } catch (IOException ioe) {
>>>>>>                     ioe.printStackTrace();
>>>>>>                 }
>>>>>>             }
>>>>>>         };
>>>>>>         testThread.start();
>>>>>>       ...
>>>>>>     }
>>>>>>
>>>>>>     private class CometChannel {
>>>>>>
>>>>>>         private static final int INPUT_BUFFER_SIZE = 512;
>>>>>>
>>>>>>         private static final int OUTPUT_BUFFER_SIZE = 512;
>>>>>>
>>>>>>         private static final String DELIMITER = "\r\n";
>>>>>>
>>>>>>         private URL url;
>>>>>>
>>>>>>         private BufferedReader inputReader;
>>>>>>
>>>>>>         private PrintWriter outputWriter;
>>>>>>
>>>>>>         private Socket socket;
>>>>>>
>>>>>>         public CometChannel(URL url) throws IOException {
>>>>>>             this.url = url;
>>>>>>             initConnection();
>>>>>>         }
>>>>>>
>>>>>>         private void initSocket() throws IOException {
>>>>>>             int port = url.getPort();
>>>>>>             port = (port < 0) ? url.getDefaultPort() : port;
>>>>>>             try {
>>>>>>                 socket = new Socket(url.getHost(), port);
>>>>>>                 socket.setKeepAlive(true);
>>>>>>                 inputReader = new BufferedReader(new
>>>>>> InputStreamReader(socket.getInputStream()), INPUT_BUFFER_SIZE);
>>>>>>                 outputWriter = new PrintWriter(new BufferedWriter(new
>>>>>> OutputStreamWriter(socket.getOutputStream()),
>>>>>>                         OUTPUT_BUFFER_SIZE));
>>>>>>             } catch (NoRouteToHostException nrthe) {
>>>>>>                 System.out.println("host: " + url.getHost());
>>>>>>                 nrthe.printStackTrace();
>>>>>>             }
>>>>>>         }
>>>>>>
>>>>>>         private void initConnection() throws IOException {
>>>>>>             initSocket();
>>>>>>             sendHeaders();
>>>>>>         }
>>>>>>
>>>>>>         private void sendHeaders() {
>>>>>>             String path = url.getPath();
>>>>>>             StringBuffer outputBuffer = new StringBuffer();
>>>>>>             outputBuffer.append("POST " + path + " HTTP/1.1" + DELIMITER);
>>>>>>             outputBuffer.append("Host: " + url.getHost() + DELIMITER);
>>>>>>             outputBuffer.append("User-Agent: CometTestApplet" + DELIMITER);
>>>>>>             outputBuffer.append("Connection: keep-alive" + DELIMITER);
>>>>>>             outputBuffer.append("Content-Type: text/plain" + DELIMITER);
>>>>>>             outputBuffer.append("Transfer-Encoding: chunked" + DELIMITER);
>>>>>>             outputBuffer.append(DELIMITER);
>>>>>>             synchronized (outputWriter) {
>>>>>>                 outputWriter.print(outputBuffer.toString());
>>>>>>             }
>>>>>>         }
>>>>>>
>>>>>>         public void send(String chunkData) throws IOException {
>>>>>>             // chunk length field in hex
>>>>>>             String hexChunkLength = Integer.toHexString(chunkData.length());
>>>>>>
>>>>>>             StringBuffer outputBuffer = new StringBuffer();
>>>>>>             outputBuffer.append(hexChunkLength);
>>>>>>             outputBuffer.append(DELIMITER);
>>>>>>             outputBuffer.append(chunkData);
>>>>>>             outputBuffer.append(DELIMITER);
>>>>>>             synchronized (outputWriter) {
>>>>>>                 outputWriter.print(outputBuffer.toString());
>>>>>>                 outputWriter.flush();
>>>>>>             }
>>>>>>         }
>>>>>>
>>>>>>         private String readChunk() throws IOException {
>>>>>>             StringBuffer inputBuffer = new StringBuffer();
>>>>>>             String hexChunkSize = inputReader.readLine();
>>>>>>             if (hexChunkSize != null) {
>>>>>>                 int chunkSize = Integer.parseInt(hexChunkSize, 16);
>>>>>>                 int charsRead = 0;
>>>>>>
>>>>>>                 char[] buf = new char[chunkSize];
>>>>>>                 do {
>>>>>>                     int n = inputReader.read(buf);
>>>>>>                     charsRead += n;
>>>>>>                     if (n > 0) {
>>>>>>                         inputBuffer.append(new String(buf, 0, n));
>>>>>>                     } else if (n < 0) {
>>>>>>                         // occurs when connection is closed, often in response
>>>>>>                         // to http session timeout from server
>>>>>>                         throw new IOException("no bytes read");
>>>>>>                     }
>>>>>>                 } while (charsRead < chunkSize);
>>>>>>                 // extra \r\n sent after chunk - part of protocol
>>>>>>                 inputReader.readLine();
>>>>>>             }
>>>>>>             return inputBuffer.toString();
>>>>>>         }
>>>>>>
>>>>>>         public String receive() throws IOException {
>>>>>>             readHeaders();
>>>>>>             return readChunk();
>>>>>>         }
>>>>>>
>>>>>>         private void readHeaders() throws IOException {
>>>>>>             String header;
>>>>>>             while ((header = inputReader.readLine()) != null) {
>>>>>>                 System.out.println("header: " + header);
>>>>>>                 if (header.length() == 0) {
>>>>>>                     break;
>>>>>>                 }
>>>>>>             }
>>>>>>         }
>>>>>>       ...
>>>>>>     }
>>>>>>
>>>>>> SERVER
>>>>>> ------
>>>>>> public class CometTestServlet extends HttpServlet implements CometProcessor {
>>>>>>     private static final long serialVersionUID = 5472498184127924791L;
>>>>>>
>>>>>>     public void event(CometEvent cometEvent) throws IOException,
>>>>>> ServletException {
>>>>>>         HttpServletRequest request = cometEvent.getHttpServletRequest();
>>>>>>         HttpSession httpSession = request.getSession(true);
>>>>>>         if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
>>>>>>             cometEvent.setTimeout(3 * 60 * 60 * 1000); // 3 hours
>>>>>>             // tell the http session not to timeout - will invalidate it on
>>>>>>             // error or end
>>>>>>             httpSession.setMaxInactiveInterval(-1);
>>>>>>         } else if (cometEvent.getEventType() == CometEvent.EventType.ERROR) {
>>>>>>             handleErrorEvent(cometEvent, httpSession);
>>>>>>         } else if (cometEvent.getEventType() == CometEvent.EventType.END) {
>>>>>>             close(cometEvent, httpSession);
>>>>>>         } else if (cometEvent.getEventType() == CometEvent.EventType.READ) {
>>>>>>             handleReadEvent(cometEvent);
>>>>>>         }
>>>>>>     }
>>>>>>
>>>>>>     protected void handleErrorEvent(CometEvent cometEvent, HttpSession
>>>>>> httpSession) throws IOException {
>>>>>>         if (cometEvent.getEventSubType() != CometEvent.EventSubType.TIMEOUT) {
>>>>>>             close(cometEvent, httpSession);
>>>>>>         }
>>>>>>     }
>>>>>>
>>>>>>     private void close(CometEvent cometEvent, HttpSession httpSession)
>>>>>> throws IOException {
>>>>>>         cometEvent.close();
>>>>>>         httpSession.invalidate();
>>>>>>     }
>>>>>>
>>>>>>     private void handleReadEvent(CometEvent cometEvent) throws
>>>>>> IOException, ServletException {
>>>>>>         ServerCometChannel talker = new ServerCometChannel(cometEvent);
>>>>>>         respond(talker);
>>>>>>     }
>>>>>>
>>>>>>     private void respond(ServerCometChannel channel) throws IOException {
>>>>>>         String clientMessage = channel.receive();
>>>>>>
>>>>>>         if (clientMessage != null && clientMessage.length() > 0) {
>>>>>>             channel.send("comet succeeded");
>>>>>>         }
>>>>>>     }
>>>>>>
>>>>>>     private class ServerCometChannel {
>>>>>>
>>>>>>         private static final int OUTPUT_BUFFER_SIZE = 512;
>>>>>>
>>>>>>         private CometEvent cometEvent;
>>>>>>
>>>>>>         private InputStream inputStream;
>>>>>>
>>>>>>         private PrintWriter outputWriter;
>>>>>>
>>>>>>         public ServerCometChannel(CometEvent cometEvent) throws
>>>>>> IOException, ServletException {
>>>>>>             this.cometEvent = cometEvent;
>>>>>>             inputStream = cometEvent.getHttpServletRequest().getInputStream();
>>>>>>             OutputStream outputStream =
>>>>>> cometEvent.getHttpServletResponse().getOutputStream();
>>>>>>             this.outputWriter = new PrintWriter(new BufferedWriter(new
>>>>>> OutputStreamWriter(outputStream),
>>>>>>                     OUTPUT_BUFFER_SIZE));
>>>>>>         }
>>>>>>
>>>>>>         private String receive() throws IOException {
>>>>>>             StringBuffer buffer = new StringBuffer();
>>>>>>             byte[] buf = new byte[512];
>>>>>>             while (inputStream.available() > 0) {
>>>>>>                 int n = inputStream.read(buf);
>>>>>>                 if (n > 0) {
>>>>>>                     buffer.append(new String(buf, 0, n));
>>>>>>                 }
>>>>>>             }
>>>>>>             return buffer.toString();
>>>>>>         }
>>>>>>
>>>>>>         public void send(String msg) {
>>>>>>             synchronized (cometEvent.getHttpServletResponse()) {
>>>>>>                 outputWriter.print(msg);
>>>>>>                 outputWriter.flush();
>>>>>>             }
>>>>>>         }
>>>>>>
>>>>>>         public void close() throws IOException {
>>>>>>             inputStream.close();
>>>>>>             outputWriter.close();
>>>>>>         }
>>>>>>     }
>>>>>>
>>>>>> ---------------------------------------------------------------------
>>>>>> To start a new topic, e-mail: users@tomcat.apache.org
>>>>>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>>>>>> For additional commands, e-mail: users-help@tomcat.apache.org
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>             
>>>>> ---------------------------------------------------------------------
>>>>> To start a new topic, e-mail: users@tomcat.apache.org
>>>>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>>>>> For additional commands, e-mail: users-help@tomcat.apache.org
>>>>>
>>>>>
>>>>>
>>>>>           
>>>> ---------------------------------------------------------------------
>>>> To start a new topic, e-mail: users@tomcat.apache.org
>>>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>>>> For additional commands, e-mail: users-help@tomcat.apache.org
>>>>
>>>>
>>>>
>>>>
>>>>         
>>> ---------------------------------------------------------------------
>>> To start a new topic, e-mail: users@tomcat.apache.org
>>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>>> For additional commands, e-mail: users-help@tomcat.apache.org
>>>
>>>
>>>       
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>
>
>   


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: comet questions

Posted by Peter Warren <to...@gmail.com>.
Anyone else experiencing comet timeout problems with the nio connector
and the latest 6.0.x trunk?

My cometEvent.setTimeout(...) setting is ignored, but I do receive
comet timeouts based on the connectionTimeout setting for the nio
connector.  Setting the connectionTimeout to 10 secs gives me a comet
timeout event every 10 secs.  Setting it to 2 mins gives a comet
timeout every 2 mins.

The docs don't mention any link between the connectionTimeout settings
and comet timeout events that I can find.

Connector config:
    <Connector port="80"
protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="500"
connectionTimeout="10000" keepAliveTimeout="30000"
maxKeepAliveRequests="-1" socket.soKeepAlive="true"
socket.appReadBufSize="2048" socket.appWriteBufSize="2048"
socket.rxBufSize="2048" socket.txBufSize="2048"
acceptorThreadCount="2" redirectPort="8443" />

On Jan 9, 2008 12:23 PM, Peter Warren <to...@gmail.com> wrote:
> Using the nio connector from the latest 6.0.x trunk, I'm failing to
> receive any comet timeouts.  I set the comet timeout to 5 secs but,
> after waiting much longer than 5 secs, the only two events I receive
> are begin and read.
>
> event: BEGIN, subtype: null
>         for servlet: com.seekspeak.server.debug.CometTestServlet
>         time: Wed Jan 09 12:12:28 PST 2008
>         on cometEvent: org.apache.catalina.connector.CometEventImpl@1b3278a
>         with "org.apache.tomcat.comet.timeout" attribute: null
>         with "org.apache.tomcat.comet.timeout.support" attribute: true
> event: READ, subtype: null
>         for servlet: com.seekspeak.server.debug.CometTestServlet
>         time: Wed Jan 09 12:12:28 PST 2008
>         on cometEvent: org.apache.catalina.connector.CometEventImpl@1b3278a
>         with "org.apache.tomcat.comet.timeout" attribute: 5000
>         with "org.apache.tomcat.comet.timeout.support" attribute: true
>
> I see that the Http11NioProcessor changed some comet timeout specific
> code from the previous rev.  Could this be having an impact?
>
> Below is my test client and test servlet.  Am I doing something wrong?
>
> Thanks,
> Peter
>
> SERVLET
> ---------------
> public class CometTestServlet extends HttpServlet implements CometProcessor {
>
>     public void event(CometEvent cometEvent) throws IOException,
> ServletException {
>         System.out.println("event: " + cometEvent.getEventType() + ",
> subtype: " + cometEvent.getEventSubType());
>         System.out.println("\tfor servlet: " + this.getClass().getName());
>         System.out.println("\ttime: " + new Date(System.currentTimeMillis()));
>         System.out.println("\ton cometEvent: " + cometEvent);
>         System.out.println("\twith \"org.apache.tomcat.comet.timeout\"
> attribute: "
>                 +
> cometEvent.getHttpServletRequest().getAttribute("org.apache.tomcat.comet.timeout"));
>         System.out.println("\twith
> \"org.apache.tomcat.comet.timeout.support\" attribute: "
>                 +
> cometEvent.getHttpServletRequest().getAttribute("org.apache.tomcat.comet.timeout.support"));
>         if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
>             cometEvent.setTimeout(5 * 1000);
>         } else if (cometEvent.getEventType() == CometEvent.EventType.ERROR) {
>             cometEvent.close();
>         } else if (cometEvent.getEventType() == CometEvent.EventType.END) {
>             cometEvent.close();
>         } else if (cometEvent.getEventType() == CometEvent.EventType.READ) {
>             handleReadEvent(cometEvent);
>         }
>     }
>
>
>     private void handleReadEvent(CometEvent cometEvent) throws
> IOException, ServletException {
>         ServerCometChannel talker = new ServerCometChannel(cometEvent);
>         respond(talker);
>     }
>
>     private void respond(ServerCometChannel channel) throws IOException {
>         String clientMessage = channel.receive();
>         if (clientMessage != null && clientMessage.length() > 0) {
>             channel.send("comet succeeded");
>         }
>     }
>
>     private class ServerCometChannel {
>
>         private static final int OUTPUT_BUFFER_SIZE = 512;
>
>         private CometEvent cometEvent;
>
>         private InputStream inputStream;
>
>         private PrintWriter outputWriter;
>
>         public ServerCometChannel(CometEvent cometEvent) throws
> IOException, ServletException {
>             this.cometEvent = cometEvent;
>             inputStream = cometEvent.getHttpServletRequest().getInputStream();
>             OutputStream outputStream =
> cometEvent.getHttpServletResponse().getOutputStream();
>             this.outputWriter = new PrintWriter(new BufferedWriter(new
> OutputStreamWriter(outputStream),
>                     OUTPUT_BUFFER_SIZE));
>         }
>
>         private String receive() throws IOException {
>             StringBuffer buffer = new StringBuffer();
>             byte[] buf = new byte[512];
>             while (inputStream.available() > 0) {
>                 int n = inputStream.read(buf);
>                 if (n > 0) {
>                     buffer.append(new String(buf, 0, n));
>                 }
>             }
>             return buffer.toString();
>         }
>
>         public void send(String msg) {
>             synchronized (cometEvent.getHttpServletResponse()) {
>                 outputWriter.print(msg);
>                 outputWriter.flush();
>                 try {
>                     cometEvent.getHttpServletResponse().flushBuffer();
>                 } catch (IOException ioe) {
>                     ioe.printStackTrace();
>                 }
>             }
>         }
>     }
> }
>
> CLIENT
> ----------
> public class CometTest {
>
>     public static void main(String[] args) throws Exception {
>         CometTest test = new CometTest();
>         test.test();
>     }
>
>     private void test() throws Exception {
>         URL url = new URL("http://www.seekspeak.com/CometTest");
>         CometChannel channel = new CometChannel(url);
>         channel.send("test");
>         String received = channel.receive();
>         System.out.println("received: " + received);
>         Thread.sleep(60 * 60 * 1000);
>     }
>
>     private class CometChannel {
>
>         private static final int INPUT_BUFFER_SIZE = 512;
>
>         private static final int OUTPUT_BUFFER_SIZE = 512;
>
>         private static final String DELIMITER = "\r\n";
>
>         private URL url;
>
>         private BufferedReader inputReader;
>
>         private PrintWriter outputWriter;
>
>         private Socket socket;
>
>         private boolean firstRead = true;
>
>
>         public CometChannel(URL url) throws IOException {
>             this.url = url;
>             initConnection();
>         }
>
>         private void initSocket() throws IOException {
>             int port = url.getPort();
>             port = (port < 0) ? url.getDefaultPort() : port;
>             try {
>                 socket = new Socket(url.getHost(), port);
>                 socket.setKeepAlive(true);
>                 inputReader = new BufferedReader(new
> InputStreamReader(socket.getInputStream()), INPUT_BUFFER_SIZE);
>                 outputWriter = new PrintWriter(new BufferedWriter(new
> OutputStreamWriter(socket.getOutputStream()),
>                         OUTPUT_BUFFER_SIZE));
>             } catch (NoRouteToHostException nrthe) {
>                 System.out.println("host: " + url.getHost());
>                 nrthe.printStackTrace();
>             }
>         }
>
>         private void initConnection() throws IOException {
>             initSocket();
>             sendHeaders();
>         }
>
>         private void sendHeaders() {
>             String path = url.getPath();
>             StringBuffer outputBuffer = new StringBuffer();
>             outputBuffer.append("POST " + path + " HTTP/1.1" + DELIMITER);
>             outputBuffer.append("Host: " + url.getHost() + DELIMITER);
>             outputBuffer.append("User-Agent: CometTestApplet" + DELIMITER);
>             outputBuffer.append("Connection: keep-alive" + DELIMITER);
>             outputBuffer.append("Content-Type: text/plain" + DELIMITER);
>             outputBuffer.append("Transfer-Encoding: chunked" + DELIMITER);
>             outputBuffer.append(DELIMITER);
>             synchronized (outputWriter) {
>                 outputWriter.print(outputBuffer.toString());
>             }
>         }
>
>         public void send(String chunkData) throws IOException {
>             String hexChunkLength = Integer.toHexString(chunkData.length());
>
>             StringBuffer outputBuffer = new StringBuffer();
>             outputBuffer.append(hexChunkLength);
>             outputBuffer.append(DELIMITER);
>             outputBuffer.append(chunkData);
>             outputBuffer.append(DELIMITER);
>             synchronized (outputWriter) {
>                 outputWriter.print(outputBuffer.toString());
>                 outputWriter.flush();
>             }
>         }
>
>         private String readChunk() throws IOException {
>             StringBuffer inputBuffer = new StringBuffer();
>             String hexChunkSize = inputReader.readLine();
>             System.out.println("chunk size: " + hexChunkSize);
>             if (hexChunkSize != null) {
>                 int chunkSize = Integer.parseInt(hexChunkSize, 16);
>                 int charsRead = 0;
>
>                 char[] buf = new char[chunkSize];
>                 do {
>                     int n = inputReader.read(buf);
>                     charsRead += n;
>                     if (n > 0) {
>                         inputBuffer.append(new String(buf, 0, n));
>                     } else if (n < 0) {
>                         // occurs when connection is closed, often in response
>                         // to http session timeout from server
>                         throw new IOException("no bytes read");
>                     }
>                 } while (charsRead < chunkSize);
>                 // extra \r\n sent after chunk - part of protocol
>                 inputReader.readLine();
>             }
>             return inputBuffer.toString();
>         }
>
>         public String receive() throws IOException {
>             if (firstRead) {
>                 firstRead = false;
>                 readHeaders();
>             }
>             return readChunk();
>         }
>
>         private void readHeaders() throws IOException {
>             String header;
>             while ((header = inputReader.readLine()) != null) {
>                 System.out.println("header: " + header);
>                 if (header.length() == 0) {
>                     break;
>                 }
>             }
>         }
>     }
> }
>
>
>
> On Jan 7, 2008 4:43 PM, Filip Hanik - Dev Lists <de...@hanik.com> wrote:
> > The time when it is called without a subtype, is if the
> > application(servlet) has an unhandled exception
> >
> > in terms of timeout, that should work just dandy, unless the client
> > disconnects, at which point at which point you might get a subtype of
> > IOEXCEPTION, or CLIENT_DISCONNECT
> > depending on the OS
> >
> > Filip
> >
> >
> > Peter Warren wrote:
> > > Using the NIO connector: protocol="org.apache.coyote.http11.Http11NioProtocol".
> > >
> > > I'll add response.flushBuffer() and see if that helps.
> > >
> > > The tomcat version I was testing against was current with svn as of
> > > last Friday.  I just updated and the only files that are new are:
> > > catalina.policy
> > > STATUS.txt
> > > changelog.xml
> > >
> > > Any ideas about the timeout setting or the comet error event without a subtype?
> > >
> > > Thanks for your response!
> > >
> > > Peter
> > >
> > > On Jan 7, 2008 12:44 PM, Filip Hanik - Dev Lists <de...@hanik.com> wrote:
> > >
> > >> what connector are you using?
> > >> I would try to use response.flushBuffer when you wanna flush it out (ie
> > >> after you've written to and flushed your stream).
> > >>
> > >> also, there have been some bug fixes, that you can get from SVN, or wait
> > >> for 6.0.16 to come out
> > >>
> > >> Filip
> > >>
> > >>
> > >> Peter Warren wrote:
> > >>
> > >>> I have some comet questions.  I'm using the tomcat 6.0.x trunk as of
> > >>> last Friday.
> > >>>
> > >>> 1) My comet event timeout setting being honored.  How come?  I set the
> > >>> timeout for 3 hours but a timeout event gets generated every 2
> > >>> minutes.  If I inspect the comet event for which the timeout is
> > >>> triggered, I see a setting for the request attribute of:
> > >>> org.apache.tomcat.comet.timeout=10800000.
> > >>>
> > >>> I set it as follows:
> > >>>
> > >>>     public void event(CometEvent cometEvent) throws IOException,
> > >>> ServletException {
> > >>>       ...
> > >>>         if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
> > >>>           // COMET_TIMEOUT = 3 * 60 * 60 * 1000
> > >>>             cometEvent.setTimeout(TimingConstants.COMET_TIMEOUT);
> > >>>
> > >>> Do I need to set something else as well?
> > >>>
> > >>> 2) Occasionally I'm getting a comet event of type ERROR without any
> > >>> subtype (i.e. not TIMEOUT, CLIENT_DISCONNECT, etc.).  What does that
> > >>> indicate?  I don't see any errors in my catalina log.
> > >>>
> > >>> 3) Reading the response from a comet servlet fails for one of my
> > >>> client machines.  I wrote a simple test to check the problem.  This
> > >>> test succeeds for many other users.  For the failing client, the
> > >>> client request is received by the comet servlet, and the servlet's
> > >>> response is written and flushed to the stream.  The client then simply
> > >>> waits indefinitely trying to read the response.  The failing client is
> > >>> a Windows XP machine.  Could anyone shed some light on why this might
> > >>> be happening, or give me some clues as to how to debug?  Could it be a
> > >>> firewall issue on the client end, a router issue on my end?
> > >>>
> > >>> The test is currently up at: http://www.seekspeak.com/test.html.  It
> > >>> tests: a http connection to a normal servlet, then a comet connection
> > >>> to a comet servlet using httpurlconnection, then a comet connection to
> > >>> a comet servlet using a socket.  For the failing client, both comet
> > >>> tests fail.
> > >>>
> > >>> Below is some of the test code for the raw socket test.
> > >>>
> > >>> Thanks for any help!
> > >>>
> > >>> Peter
> > >>>
> > >>> CLIENT
> > >>> ------
> > >>>     private void testCometConnection() throws IOException {
> > >>>       ...
> > >>>         URL url = new URL("http://www.seekspeak.com/CometTest");
> > >>>         channel = new CometChannel(url);
> > >>>         Thread testThread = new Thread() {
> > >>>             public void run() {
> > >>>                 try {
> > >>>                     channel.send("test");
> > >>>                     String received = channel.receive();
> > >>>                     ...
> > >>>                     }
> > >>>                 } catch (IOException ioe) {
> > >>>                     ioe.printStackTrace();
> > >>>                 }
> > >>>             }
> > >>>         };
> > >>>         testThread.start();
> > >>>       ...
> > >>>     }
> > >>>
> > >>>     private class CometChannel {
> > >>>
> > >>>         private static final int INPUT_BUFFER_SIZE = 512;
> > >>>
> > >>>         private static final int OUTPUT_BUFFER_SIZE = 512;
> > >>>
> > >>>         private static final String DELIMITER = "\r\n";
> > >>>
> > >>>         private URL url;
> > >>>
> > >>>         private BufferedReader inputReader;
> > >>>
> > >>>         private PrintWriter outputWriter;
> > >>>
> > >>>         private Socket socket;
> > >>>
> > >>>         public CometChannel(URL url) throws IOException {
> > >>>             this.url = url;
> > >>>             initConnection();
> > >>>         }
> > >>>
> > >>>         private void initSocket() throws IOException {
> > >>>             int port = url.getPort();
> > >>>             port = (port < 0) ? url.getDefaultPort() : port;
> > >>>             try {
> > >>>                 socket = new Socket(url.getHost(), port);
> > >>>                 socket.setKeepAlive(true);
> > >>>                 inputReader = new BufferedReader(new
> > >>> InputStreamReader(socket.getInputStream()), INPUT_BUFFER_SIZE);
> > >>>                 outputWriter = new PrintWriter(new BufferedWriter(new
> > >>> OutputStreamWriter(socket.getOutputStream()),
> > >>>                         OUTPUT_BUFFER_SIZE));
> > >>>             } catch (NoRouteToHostException nrthe) {
> > >>>                 System.out.println("host: " + url.getHost());
> > >>>                 nrthe.printStackTrace();
> > >>>             }
> > >>>         }
> > >>>
> > >>>         private void initConnection() throws IOException {
> > >>>             initSocket();
> > >>>             sendHeaders();
> > >>>         }
> > >>>
> > >>>         private void sendHeaders() {
> > >>>             String path = url.getPath();
> > >>>             StringBuffer outputBuffer = new StringBuffer();
> > >>>             outputBuffer.append("POST " + path + " HTTP/1.1" + DELIMITER);
> > >>>             outputBuffer.append("Host: " + url.getHost() + DELIMITER);
> > >>>             outputBuffer.append("User-Agent: CometTestApplet" + DELIMITER);
> > >>>             outputBuffer.append("Connection: keep-alive" + DELIMITER);
> > >>>             outputBuffer.append("Content-Type: text/plain" + DELIMITER);
> > >>>             outputBuffer.append("Transfer-Encoding: chunked" + DELIMITER);
> > >>>             outputBuffer.append(DELIMITER);
> > >>>             synchronized (outputWriter) {
> > >>>                 outputWriter.print(outputBuffer.toString());
> > >>>             }
> > >>>         }
> > >>>
> > >>>         public void send(String chunkData) throws IOException {
> > >>>             // chunk length field in hex
> > >>>             String hexChunkLength = Integer.toHexString(chunkData.length());
> > >>>
> > >>>             StringBuffer outputBuffer = new StringBuffer();
> > >>>             outputBuffer.append(hexChunkLength);
> > >>>             outputBuffer.append(DELIMITER);
> > >>>             outputBuffer.append(chunkData);
> > >>>             outputBuffer.append(DELIMITER);
> > >>>             synchronized (outputWriter) {
> > >>>                 outputWriter.print(outputBuffer.toString());
> > >>>                 outputWriter.flush();
> > >>>             }
> > >>>         }
> > >>>
> > >>>         private String readChunk() throws IOException {
> > >>>             StringBuffer inputBuffer = new StringBuffer();
> > >>>             String hexChunkSize = inputReader.readLine();
> > >>>             if (hexChunkSize != null) {
> > >>>                 int chunkSize = Integer.parseInt(hexChunkSize, 16);
> > >>>                 int charsRead = 0;
> > >>>
> > >>>                 char[] buf = new char[chunkSize];
> > >>>                 do {
> > >>>                     int n = inputReader.read(buf);
> > >>>                     charsRead += n;
> > >>>                     if (n > 0) {
> > >>>                         inputBuffer.append(new String(buf, 0, n));
> > >>>                     } else if (n < 0) {
> > >>>                         // occurs when connection is closed, often in response
> > >>>                         // to http session timeout from server
> > >>>                         throw new IOException("no bytes read");
> > >>>                     }
> > >>>                 } while (charsRead < chunkSize);
> > >>>                 // extra \r\n sent after chunk - part of protocol
> > >>>                 inputReader.readLine();
> > >>>             }
> > >>>             return inputBuffer.toString();
> > >>>         }
> > >>>
> > >>>         public String receive() throws IOException {
> > >>>             readHeaders();
> > >>>             return readChunk();
> > >>>         }
> > >>>
> > >>>         private void readHeaders() throws IOException {
> > >>>             String header;
> > >>>             while ((header = inputReader.readLine()) != null) {
> > >>>                 System.out.println("header: " + header);
> > >>>                 if (header.length() == 0) {
> > >>>                     break;
> > >>>                 }
> > >>>             }
> > >>>         }
> > >>>       ...
> > >>>     }
> > >>>
> > >>> SERVER
> > >>> ------
> > >>> public class CometTestServlet extends HttpServlet implements CometProcessor {
> > >>>     private static final long serialVersionUID = 5472498184127924791L;
> > >>>
> > >>>     public void event(CometEvent cometEvent) throws IOException,
> > >>> ServletException {
> > >>>         HttpServletRequest request = cometEvent.getHttpServletRequest();
> > >>>         HttpSession httpSession = request.getSession(true);
> > >>>         if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
> > >>>             cometEvent.setTimeout(3 * 60 * 60 * 1000); // 3 hours
> > >>>             // tell the http session not to timeout - will invalidate it on
> > >>>             // error or end
> > >>>             httpSession.setMaxInactiveInterval(-1);
> > >>>         } else if (cometEvent.getEventType() == CometEvent.EventType.ERROR) {
> > >>>             handleErrorEvent(cometEvent, httpSession);
> > >>>         } else if (cometEvent.getEventType() == CometEvent.EventType.END) {
> > >>>             close(cometEvent, httpSession);
> > >>>         } else if (cometEvent.getEventType() == CometEvent.EventType.READ) {
> > >>>             handleReadEvent(cometEvent);
> > >>>         }
> > >>>     }
> > >>>
> > >>>     protected void handleErrorEvent(CometEvent cometEvent, HttpSession
> > >>> httpSession) throws IOException {
> > >>>         if (cometEvent.getEventSubType() != CometEvent.EventSubType.TIMEOUT) {
> > >>>             close(cometEvent, httpSession);
> > >>>         }
> > >>>     }
> > >>>
> > >>>     private void close(CometEvent cometEvent, HttpSession httpSession)
> > >>> throws IOException {
> > >>>         cometEvent.close();
> > >>>         httpSession.invalidate();
> > >>>     }
> > >>>
> > >>>     private void handleReadEvent(CometEvent cometEvent) throws
> > >>> IOException, ServletException {
> > >>>         ServerCometChannel talker = new ServerCometChannel(cometEvent);
> > >>>         respond(talker);
> > >>>     }
> > >>>
> > >>>     private void respond(ServerCometChannel channel) throws IOException {
> > >>>         String clientMessage = channel.receive();
> > >>>
> > >>>         if (clientMessage != null && clientMessage.length() > 0) {
> > >>>             channel.send("comet succeeded");
> > >>>         }
> > >>>     }
> > >>>
> > >>>     private class ServerCometChannel {
> > >>>
> > >>>         private static final int OUTPUT_BUFFER_SIZE = 512;
> > >>>
> > >>>         private CometEvent cometEvent;
> > >>>
> > >>>         private InputStream inputStream;
> > >>>
> > >>>         private PrintWriter outputWriter;
> > >>>
> > >>>         public ServerCometChannel(CometEvent cometEvent) throws
> > >>> IOException, ServletException {
> > >>>             this.cometEvent = cometEvent;
> > >>>             inputStream = cometEvent.getHttpServletRequest().getInputStream();
> > >>>             OutputStream outputStream =
> > >>> cometEvent.getHttpServletResponse().getOutputStream();
> > >>>             this.outputWriter = new PrintWriter(new BufferedWriter(new
> > >>> OutputStreamWriter(outputStream),
> > >>>                     OUTPUT_BUFFER_SIZE));
> > >>>         }
> > >>>
> > >>>         private String receive() throws IOException {
> > >>>             StringBuffer buffer = new StringBuffer();
> > >>>             byte[] buf = new byte[512];
> > >>>             while (inputStream.available() > 0) {
> > >>>                 int n = inputStream.read(buf);
> > >>>                 if (n > 0) {
> > >>>                     buffer.append(new String(buf, 0, n));
> > >>>                 }
> > >>>             }
> > >>>             return buffer.toString();
> > >>>         }
> > >>>
> > >>>         public void send(String msg) {
> > >>>             synchronized (cometEvent.getHttpServletResponse()) {
> > >>>                 outputWriter.print(msg);
> > >>>                 outputWriter.flush();
> > >>>             }
> > >>>         }
> > >>>
> > >>>         public void close() throws IOException {
> > >>>             inputStream.close();
> > >>>             outputWriter.close();
> > >>>         }
> > >>>     }
> > >>>
> > >>> ---------------------------------------------------------------------
> > >>> To start a new topic, e-mail: users@tomcat.apache.org
> > >>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> > >>> For additional commands, e-mail: users-help@tomcat.apache.org
> > >>>
> > >>>
> > >>>
> > >>>
> > >>>
> > >> ---------------------------------------------------------------------
> > >> To start a new topic, e-mail: users@tomcat.apache.org
> > >> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> > >> For additional commands, e-mail: users-help@tomcat.apache.org
> > >>
> > >>
> > >>
> > >
> > > ---------------------------------------------------------------------
> > > To start a new topic, e-mail: users@tomcat.apache.org
> > > To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> > > For additional commands, e-mail: users-help@tomcat.apache.org
> > >
> > >
> > >
> > >
> >
> >
> > ---------------------------------------------------------------------
> > To start a new topic, e-mail: users@tomcat.apache.org
> > To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> > For additional commands, e-mail: users-help@tomcat.apache.org
> >
> >
>

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: comet questions

Posted by Peter Warren <to...@gmail.com>.
Using the nio connector from the latest 6.0.x trunk, I'm failing to
receive any comet timeouts.  I set the comet timeout to 5 secs but,
after waiting much longer than 5 secs, the only two events I receive
are begin and read.

event: BEGIN, subtype: null
        for servlet: com.seekspeak.server.debug.CometTestServlet
        time: Wed Jan 09 12:12:28 PST 2008
        on cometEvent: org.apache.catalina.connector.CometEventImpl@1b3278a
        with "org.apache.tomcat.comet.timeout" attribute: null
        with "org.apache.tomcat.comet.timeout.support" attribute: true
event: READ, subtype: null
        for servlet: com.seekspeak.server.debug.CometTestServlet
        time: Wed Jan 09 12:12:28 PST 2008
        on cometEvent: org.apache.catalina.connector.CometEventImpl@1b3278a
        with "org.apache.tomcat.comet.timeout" attribute: 5000
        with "org.apache.tomcat.comet.timeout.support" attribute: true

I see that the Http11NioProcessor changed some comet timeout specific
code from the previous rev.  Could this be having an impact?

Below is my test client and test servlet.  Am I doing something wrong?

Thanks,
Peter

SERVLET
---------------
public class CometTestServlet extends HttpServlet implements CometProcessor {

    public void event(CometEvent cometEvent) throws IOException,
ServletException {
        System.out.println("event: " + cometEvent.getEventType() + ",
subtype: " + cometEvent.getEventSubType());
        System.out.println("\tfor servlet: " + this.getClass().getName());
        System.out.println("\ttime: " + new Date(System.currentTimeMillis()));
        System.out.println("\ton cometEvent: " + cometEvent);
        System.out.println("\twith \"org.apache.tomcat.comet.timeout\"
attribute: "
                +
cometEvent.getHttpServletRequest().getAttribute("org.apache.tomcat.comet.timeout"));
        System.out.println("\twith
\"org.apache.tomcat.comet.timeout.support\" attribute: "
                +
cometEvent.getHttpServletRequest().getAttribute("org.apache.tomcat.comet.timeout.support"));
        if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
            cometEvent.setTimeout(5 * 1000);
        } else if (cometEvent.getEventType() == CometEvent.EventType.ERROR) {
            cometEvent.close();
        } else if (cometEvent.getEventType() == CometEvent.EventType.END) {
            cometEvent.close();
        } else if (cometEvent.getEventType() == CometEvent.EventType.READ) {
            handleReadEvent(cometEvent);
        }
    }

    private void handleReadEvent(CometEvent cometEvent) throws
IOException, ServletException {
        ServerCometChannel talker = new ServerCometChannel(cometEvent);
        respond(talker);
    }

    private void respond(ServerCometChannel channel) throws IOException {
        String clientMessage = channel.receive();
        if (clientMessage != null && clientMessage.length() > 0) {
            channel.send("comet succeeded");
        }
    }

    private class ServerCometChannel {

        private static final int OUTPUT_BUFFER_SIZE = 512;

        private CometEvent cometEvent;

        private InputStream inputStream;

        private PrintWriter outputWriter;

        public ServerCometChannel(CometEvent cometEvent) throws
IOException, ServletException {
            this.cometEvent = cometEvent;
            inputStream = cometEvent.getHttpServletRequest().getInputStream();
            OutputStream outputStream =
cometEvent.getHttpServletResponse().getOutputStream();
            this.outputWriter = new PrintWriter(new BufferedWriter(new
OutputStreamWriter(outputStream),
                    OUTPUT_BUFFER_SIZE));
        }

        private String receive() throws IOException {
            StringBuffer buffer = new StringBuffer();
            byte[] buf = new byte[512];
            while (inputStream.available() > 0) {
                int n = inputStream.read(buf);
                if (n > 0) {
                    buffer.append(new String(buf, 0, n));
                }
            }
            return buffer.toString();
        }

        public void send(String msg) {
            synchronized (cometEvent.getHttpServletResponse()) {
                outputWriter.print(msg);
                outputWriter.flush();
                try {
                    cometEvent.getHttpServletResponse().flushBuffer();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        }
    }
}

CLIENT
----------
public class CometTest {

    public static void main(String[] args) throws Exception {
        CometTest test = new CometTest();
        test.test();
    }

    private void test() throws Exception {
        URL url = new URL("http://www.seekspeak.com/CometTest");
        CometChannel channel = new CometChannel(url);
        channel.send("test");
        String received = channel.receive();
        System.out.println("received: " + received);
        Thread.sleep(60 * 60 * 1000);
    }

    private class CometChannel {

        private static final int INPUT_BUFFER_SIZE = 512;

        private static final int OUTPUT_BUFFER_SIZE = 512;

        private static final String DELIMITER = "\r\n";

        private URL url;

        private BufferedReader inputReader;

        private PrintWriter outputWriter;

        private Socket socket;

        private boolean firstRead = true;

        public CometChannel(URL url) throws IOException {
            this.url = url;
            initConnection();
        }

        private void initSocket() throws IOException {
            int port = url.getPort();
            port = (port < 0) ? url.getDefaultPort() : port;
            try {
                socket = new Socket(url.getHost(), port);
                socket.setKeepAlive(true);
                inputReader = new BufferedReader(new
InputStreamReader(socket.getInputStream()), INPUT_BUFFER_SIZE);
                outputWriter = new PrintWriter(new BufferedWriter(new
OutputStreamWriter(socket.getOutputStream()),
                        OUTPUT_BUFFER_SIZE));
            } catch (NoRouteToHostException nrthe) {
                System.out.println("host: " + url.getHost());
                nrthe.printStackTrace();
            }
        }

        private void initConnection() throws IOException {
            initSocket();
            sendHeaders();
        }

        private void sendHeaders() {
            String path = url.getPath();
            StringBuffer outputBuffer = new StringBuffer();
            outputBuffer.append("POST " + path + " HTTP/1.1" + DELIMITER);
            outputBuffer.append("Host: " + url.getHost() + DELIMITER);
            outputBuffer.append("User-Agent: CometTestApplet" + DELIMITER);
            outputBuffer.append("Connection: keep-alive" + DELIMITER);
            outputBuffer.append("Content-Type: text/plain" + DELIMITER);
            outputBuffer.append("Transfer-Encoding: chunked" + DELIMITER);
            outputBuffer.append(DELIMITER);
            synchronized (outputWriter) {
                outputWriter.print(outputBuffer.toString());
            }
        }

        public void send(String chunkData) throws IOException {
            String hexChunkLength = Integer.toHexString(chunkData.length());

            StringBuffer outputBuffer = new StringBuffer();
            outputBuffer.append(hexChunkLength);
            outputBuffer.append(DELIMITER);
            outputBuffer.append(chunkData);
            outputBuffer.append(DELIMITER);
            synchronized (outputWriter) {
                outputWriter.print(outputBuffer.toString());
                outputWriter.flush();
            }
        }

        private String readChunk() throws IOException {
            StringBuffer inputBuffer = new StringBuffer();
            String hexChunkSize = inputReader.readLine();
            System.out.println("chunk size: " + hexChunkSize);
            if (hexChunkSize != null) {
                int chunkSize = Integer.parseInt(hexChunkSize, 16);
                int charsRead = 0;

                char[] buf = new char[chunkSize];
                do {
                    int n = inputReader.read(buf);
                    charsRead += n;
                    if (n > 0) {
                        inputBuffer.append(new String(buf, 0, n));
                    } else if (n < 0) {
                        // occurs when connection is closed, often in response
                        // to http session timeout from server
                        throw new IOException("no bytes read");
                    }
                } while (charsRead < chunkSize);
                // extra \r\n sent after chunk - part of protocol
                inputReader.readLine();
            }
            return inputBuffer.toString();
        }

        public String receive() throws IOException {
            if (firstRead) {
                firstRead = false;
                readHeaders();
            }
            return readChunk();
        }

        private void readHeaders() throws IOException {
            String header;
            while ((header = inputReader.readLine()) != null) {
                System.out.println("header: " + header);
                if (header.length() == 0) {
                    break;
                }
            }
        }
    }
}


On Jan 7, 2008 4:43 PM, Filip Hanik - Dev Lists <de...@hanik.com> wrote:
> The time when it is called without a subtype, is if the
> application(servlet) has an unhandled exception
>
> in terms of timeout, that should work just dandy, unless the client
> disconnects, at which point at which point you might get a subtype of
> IOEXCEPTION, or CLIENT_DISCONNECT
> depending on the OS
>
> Filip
>
>
> Peter Warren wrote:
> > Using the NIO connector: protocol="org.apache.coyote.http11.Http11NioProtocol".
> >
> > I'll add response.flushBuffer() and see if that helps.
> >
> > The tomcat version I was testing against was current with svn as of
> > last Friday.  I just updated and the only files that are new are:
> > catalina.policy
> > STATUS.txt
> > changelog.xml
> >
> > Any ideas about the timeout setting or the comet error event without a subtype?
> >
> > Thanks for your response!
> >
> > Peter
> >
> > On Jan 7, 2008 12:44 PM, Filip Hanik - Dev Lists <de...@hanik.com> wrote:
> >
> >> what connector are you using?
> >> I would try to use response.flushBuffer when you wanna flush it out (ie
> >> after you've written to and flushed your stream).
> >>
> >> also, there have been some bug fixes, that you can get from SVN, or wait
> >> for 6.0.16 to come out
> >>
> >> Filip
> >>
> >>
> >> Peter Warren wrote:
> >>
> >>> I have some comet questions.  I'm using the tomcat 6.0.x trunk as of
> >>> last Friday.
> >>>
> >>> 1) My comet event timeout setting being honored.  How come?  I set the
> >>> timeout for 3 hours but a timeout event gets generated every 2
> >>> minutes.  If I inspect the comet event for which the timeout is
> >>> triggered, I see a setting for the request attribute of:
> >>> org.apache.tomcat.comet.timeout=10800000.
> >>>
> >>> I set it as follows:
> >>>
> >>>     public void event(CometEvent cometEvent) throws IOException,
> >>> ServletException {
> >>>       ...
> >>>         if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
> >>>           // COMET_TIMEOUT = 3 * 60 * 60 * 1000
> >>>             cometEvent.setTimeout(TimingConstants.COMET_TIMEOUT);
> >>>
> >>> Do I need to set something else as well?
> >>>
> >>> 2) Occasionally I'm getting a comet event of type ERROR without any
> >>> subtype (i.e. not TIMEOUT, CLIENT_DISCONNECT, etc.).  What does that
> >>> indicate?  I don't see any errors in my catalina log.
> >>>
> >>> 3) Reading the response from a comet servlet fails for one of my
> >>> client machines.  I wrote a simple test to check the problem.  This
> >>> test succeeds for many other users.  For the failing client, the
> >>> client request is received by the comet servlet, and the servlet's
> >>> response is written and flushed to the stream.  The client then simply
> >>> waits indefinitely trying to read the response.  The failing client is
> >>> a Windows XP machine.  Could anyone shed some light on why this might
> >>> be happening, or give me some clues as to how to debug?  Could it be a
> >>> firewall issue on the client end, a router issue on my end?
> >>>
> >>> The test is currently up at: http://www.seekspeak.com/test.html.  It
> >>> tests: a http connection to a normal servlet, then a comet connection
> >>> to a comet servlet using httpurlconnection, then a comet connection to
> >>> a comet servlet using a socket.  For the failing client, both comet
> >>> tests fail.
> >>>
> >>> Below is some of the test code for the raw socket test.
> >>>
> >>> Thanks for any help!
> >>>
> >>> Peter
> >>>
> >>> CLIENT
> >>> ------
> >>>     private void testCometConnection() throws IOException {
> >>>       ...
> >>>         URL url = new URL("http://www.seekspeak.com/CometTest");
> >>>         channel = new CometChannel(url);
> >>>         Thread testThread = new Thread() {
> >>>             public void run() {
> >>>                 try {
> >>>                     channel.send("test");
> >>>                     String received = channel.receive();
> >>>                     ...
> >>>                     }
> >>>                 } catch (IOException ioe) {
> >>>                     ioe.printStackTrace();
> >>>                 }
> >>>             }
> >>>         };
> >>>         testThread.start();
> >>>       ...
> >>>     }
> >>>
> >>>     private class CometChannel {
> >>>
> >>>         private static final int INPUT_BUFFER_SIZE = 512;
> >>>
> >>>         private static final int OUTPUT_BUFFER_SIZE = 512;
> >>>
> >>>         private static final String DELIMITER = "\r\n";
> >>>
> >>>         private URL url;
> >>>
> >>>         private BufferedReader inputReader;
> >>>
> >>>         private PrintWriter outputWriter;
> >>>
> >>>         private Socket socket;
> >>>
> >>>         public CometChannel(URL url) throws IOException {
> >>>             this.url = url;
> >>>             initConnection();
> >>>         }
> >>>
> >>>         private void initSocket() throws IOException {
> >>>             int port = url.getPort();
> >>>             port = (port < 0) ? url.getDefaultPort() : port;
> >>>             try {
> >>>                 socket = new Socket(url.getHost(), port);
> >>>                 socket.setKeepAlive(true);
> >>>                 inputReader = new BufferedReader(new
> >>> InputStreamReader(socket.getInputStream()), INPUT_BUFFER_SIZE);
> >>>                 outputWriter = new PrintWriter(new BufferedWriter(new
> >>> OutputStreamWriter(socket.getOutputStream()),
> >>>                         OUTPUT_BUFFER_SIZE));
> >>>             } catch (NoRouteToHostException nrthe) {
> >>>                 System.out.println("host: " + url.getHost());
> >>>                 nrthe.printStackTrace();
> >>>             }
> >>>         }
> >>>
> >>>         private void initConnection() throws IOException {
> >>>             initSocket();
> >>>             sendHeaders();
> >>>         }
> >>>
> >>>         private void sendHeaders() {
> >>>             String path = url.getPath();
> >>>             StringBuffer outputBuffer = new StringBuffer();
> >>>             outputBuffer.append("POST " + path + " HTTP/1.1" + DELIMITER);
> >>>             outputBuffer.append("Host: " + url.getHost() + DELIMITER);
> >>>             outputBuffer.append("User-Agent: CometTestApplet" + DELIMITER);
> >>>             outputBuffer.append("Connection: keep-alive" + DELIMITER);
> >>>             outputBuffer.append("Content-Type: text/plain" + DELIMITER);
> >>>             outputBuffer.append("Transfer-Encoding: chunked" + DELIMITER);
> >>>             outputBuffer.append(DELIMITER);
> >>>             synchronized (outputWriter) {
> >>>                 outputWriter.print(outputBuffer.toString());
> >>>             }
> >>>         }
> >>>
> >>>         public void send(String chunkData) throws IOException {
> >>>             // chunk length field in hex
> >>>             String hexChunkLength = Integer.toHexString(chunkData.length());
> >>>
> >>>             StringBuffer outputBuffer = new StringBuffer();
> >>>             outputBuffer.append(hexChunkLength);
> >>>             outputBuffer.append(DELIMITER);
> >>>             outputBuffer.append(chunkData);
> >>>             outputBuffer.append(DELIMITER);
> >>>             synchronized (outputWriter) {
> >>>                 outputWriter.print(outputBuffer.toString());
> >>>                 outputWriter.flush();
> >>>             }
> >>>         }
> >>>
> >>>         private String readChunk() throws IOException {
> >>>             StringBuffer inputBuffer = new StringBuffer();
> >>>             String hexChunkSize = inputReader.readLine();
> >>>             if (hexChunkSize != null) {
> >>>                 int chunkSize = Integer.parseInt(hexChunkSize, 16);
> >>>                 int charsRead = 0;
> >>>
> >>>                 char[] buf = new char[chunkSize];
> >>>                 do {
> >>>                     int n = inputReader.read(buf);
> >>>                     charsRead += n;
> >>>                     if (n > 0) {
> >>>                         inputBuffer.append(new String(buf, 0, n));
> >>>                     } else if (n < 0) {
> >>>                         // occurs when connection is closed, often in response
> >>>                         // to http session timeout from server
> >>>                         throw new IOException("no bytes read");
> >>>                     }
> >>>                 } while (charsRead < chunkSize);
> >>>                 // extra \r\n sent after chunk - part of protocol
> >>>                 inputReader.readLine();
> >>>             }
> >>>             return inputBuffer.toString();
> >>>         }
> >>>
> >>>         public String receive() throws IOException {
> >>>             readHeaders();
> >>>             return readChunk();
> >>>         }
> >>>
> >>>         private void readHeaders() throws IOException {
> >>>             String header;
> >>>             while ((header = inputReader.readLine()) != null) {
> >>>                 System.out.println("header: " + header);
> >>>                 if (header.length() == 0) {
> >>>                     break;
> >>>                 }
> >>>             }
> >>>         }
> >>>       ...
> >>>     }
> >>>
> >>> SERVER
> >>> ------
> >>> public class CometTestServlet extends HttpServlet implements CometProcessor {
> >>>     private static final long serialVersionUID = 5472498184127924791L;
> >>>
> >>>     public void event(CometEvent cometEvent) throws IOException,
> >>> ServletException {
> >>>         HttpServletRequest request = cometEvent.getHttpServletRequest();
> >>>         HttpSession httpSession = request.getSession(true);
> >>>         if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
> >>>             cometEvent.setTimeout(3 * 60 * 60 * 1000); // 3 hours
> >>>             // tell the http session not to timeout - will invalidate it on
> >>>             // error or end
> >>>             httpSession.setMaxInactiveInterval(-1);
> >>>         } else if (cometEvent.getEventType() == CometEvent.EventType.ERROR) {
> >>>             handleErrorEvent(cometEvent, httpSession);
> >>>         } else if (cometEvent.getEventType() == CometEvent.EventType.END) {
> >>>             close(cometEvent, httpSession);
> >>>         } else if (cometEvent.getEventType() == CometEvent.EventType.READ) {
> >>>             handleReadEvent(cometEvent);
> >>>         }
> >>>     }
> >>>
> >>>     protected void handleErrorEvent(CometEvent cometEvent, HttpSession
> >>> httpSession) throws IOException {
> >>>         if (cometEvent.getEventSubType() != CometEvent.EventSubType.TIMEOUT) {
> >>>             close(cometEvent, httpSession);
> >>>         }
> >>>     }
> >>>
> >>>     private void close(CometEvent cometEvent, HttpSession httpSession)
> >>> throws IOException {
> >>>         cometEvent.close();
> >>>         httpSession.invalidate();
> >>>     }
> >>>
> >>>     private void handleReadEvent(CometEvent cometEvent) throws
> >>> IOException, ServletException {
> >>>         ServerCometChannel talker = new ServerCometChannel(cometEvent);
> >>>         respond(talker);
> >>>     }
> >>>
> >>>     private void respond(ServerCometChannel channel) throws IOException {
> >>>         String clientMessage = channel.receive();
> >>>
> >>>         if (clientMessage != null && clientMessage.length() > 0) {
> >>>             channel.send("comet succeeded");
> >>>         }
> >>>     }
> >>>
> >>>     private class ServerCometChannel {
> >>>
> >>>         private static final int OUTPUT_BUFFER_SIZE = 512;
> >>>
> >>>         private CometEvent cometEvent;
> >>>
> >>>         private InputStream inputStream;
> >>>
> >>>         private PrintWriter outputWriter;
> >>>
> >>>         public ServerCometChannel(CometEvent cometEvent) throws
> >>> IOException, ServletException {
> >>>             this.cometEvent = cometEvent;
> >>>             inputStream = cometEvent.getHttpServletRequest().getInputStream();
> >>>             OutputStream outputStream =
> >>> cometEvent.getHttpServletResponse().getOutputStream();
> >>>             this.outputWriter = new PrintWriter(new BufferedWriter(new
> >>> OutputStreamWriter(outputStream),
> >>>                     OUTPUT_BUFFER_SIZE));
> >>>         }
> >>>
> >>>         private String receive() throws IOException {
> >>>             StringBuffer buffer = new StringBuffer();
> >>>             byte[] buf = new byte[512];
> >>>             while (inputStream.available() > 0) {
> >>>                 int n = inputStream.read(buf);
> >>>                 if (n > 0) {
> >>>                     buffer.append(new String(buf, 0, n));
> >>>                 }
> >>>             }
> >>>             return buffer.toString();
> >>>         }
> >>>
> >>>         public void send(String msg) {
> >>>             synchronized (cometEvent.getHttpServletResponse()) {
> >>>                 outputWriter.print(msg);
> >>>                 outputWriter.flush();
> >>>             }
> >>>         }
> >>>
> >>>         public void close() throws IOException {
> >>>             inputStream.close();
> >>>             outputWriter.close();
> >>>         }
> >>>     }
> >>>
> >>> ---------------------------------------------------------------------
> >>> To start a new topic, e-mail: users@tomcat.apache.org
> >>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> >>> For additional commands, e-mail: users-help@tomcat.apache.org
> >>>
> >>>
> >>>
> >>>
> >>>
> >> ---------------------------------------------------------------------
> >> To start a new topic, e-mail: users@tomcat.apache.org
> >> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> >> For additional commands, e-mail: users-help@tomcat.apache.org
> >>
> >>
> >>
> >
> > ---------------------------------------------------------------------
> > To start a new topic, e-mail: users@tomcat.apache.org
> > To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> > For additional commands, e-mail: users-help@tomcat.apache.org
> >
> >
> >
> >
>
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: comet questions

Posted by Filip Hanik - Dev Lists <de...@hanik.com>.
The time when it is called without a subtype, is if the 
application(servlet) has an unhandled exception

in terms of timeout, that should work just dandy, unless the client 
disconnects, at which point at which point you might get a subtype of 
IOEXCEPTION, or CLIENT_DISCONNECT
depending on the OS

Filip

Peter Warren wrote:
> Using the NIO connector: protocol="org.apache.coyote.http11.Http11NioProtocol".
>
> I'll add response.flushBuffer() and see if that helps.
>
> The tomcat version I was testing against was current with svn as of
> last Friday.  I just updated and the only files that are new are:
> catalina.policy
> STATUS.txt
> changelog.xml
>
> Any ideas about the timeout setting or the comet error event without a subtype?
>
> Thanks for your response!
>
> Peter
>
> On Jan 7, 2008 12:44 PM, Filip Hanik - Dev Lists <de...@hanik.com> wrote:
>   
>> what connector are you using?
>> I would try to use response.flushBuffer when you wanna flush it out (ie
>> after you've written to and flushed your stream).
>>
>> also, there have been some bug fixes, that you can get from SVN, or wait
>> for 6.0.16 to come out
>>
>> Filip
>>
>>
>> Peter Warren wrote:
>>     
>>> I have some comet questions.  I'm using the tomcat 6.0.x trunk as of
>>> last Friday.
>>>
>>> 1) My comet event timeout setting being honored.  How come?  I set the
>>> timeout for 3 hours but a timeout event gets generated every 2
>>> minutes.  If I inspect the comet event for which the timeout is
>>> triggered, I see a setting for the request attribute of:
>>> org.apache.tomcat.comet.timeout=10800000.
>>>
>>> I set it as follows:
>>>
>>>     public void event(CometEvent cometEvent) throws IOException,
>>> ServletException {
>>>       ...
>>>         if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
>>>           // COMET_TIMEOUT = 3 * 60 * 60 * 1000
>>>             cometEvent.setTimeout(TimingConstants.COMET_TIMEOUT);
>>>
>>> Do I need to set something else as well?
>>>
>>> 2) Occasionally I'm getting a comet event of type ERROR without any
>>> subtype (i.e. not TIMEOUT, CLIENT_DISCONNECT, etc.).  What does that
>>> indicate?  I don't see any errors in my catalina log.
>>>
>>> 3) Reading the response from a comet servlet fails for one of my
>>> client machines.  I wrote a simple test to check the problem.  This
>>> test succeeds for many other users.  For the failing client, the
>>> client request is received by the comet servlet, and the servlet's
>>> response is written and flushed to the stream.  The client then simply
>>> waits indefinitely trying to read the response.  The failing client is
>>> a Windows XP machine.  Could anyone shed some light on why this might
>>> be happening, or give me some clues as to how to debug?  Could it be a
>>> firewall issue on the client end, a router issue on my end?
>>>
>>> The test is currently up at: http://www.seekspeak.com/test.html.  It
>>> tests: a http connection to a normal servlet, then a comet connection
>>> to a comet servlet using httpurlconnection, then a comet connection to
>>> a comet servlet using a socket.  For the failing client, both comet
>>> tests fail.
>>>
>>> Below is some of the test code for the raw socket test.
>>>
>>> Thanks for any help!
>>>
>>> Peter
>>>
>>> CLIENT
>>> ------
>>>     private void testCometConnection() throws IOException {
>>>       ...
>>>         URL url = new URL("http://www.seekspeak.com/CometTest");
>>>         channel = new CometChannel(url);
>>>         Thread testThread = new Thread() {
>>>             public void run() {
>>>                 try {
>>>                     channel.send("test");
>>>                     String received = channel.receive();
>>>                     ...
>>>                     }
>>>                 } catch (IOException ioe) {
>>>                     ioe.printStackTrace();
>>>                 }
>>>             }
>>>         };
>>>         testThread.start();
>>>       ...
>>>     }
>>>
>>>     private class CometChannel {
>>>
>>>         private static final int INPUT_BUFFER_SIZE = 512;
>>>
>>>         private static final int OUTPUT_BUFFER_SIZE = 512;
>>>
>>>         private static final String DELIMITER = "\r\n";
>>>
>>>         private URL url;
>>>
>>>         private BufferedReader inputReader;
>>>
>>>         private PrintWriter outputWriter;
>>>
>>>         private Socket socket;
>>>
>>>         public CometChannel(URL url) throws IOException {
>>>             this.url = url;
>>>             initConnection();
>>>         }
>>>
>>>         private void initSocket() throws IOException {
>>>             int port = url.getPort();
>>>             port = (port < 0) ? url.getDefaultPort() : port;
>>>             try {
>>>                 socket = new Socket(url.getHost(), port);
>>>                 socket.setKeepAlive(true);
>>>                 inputReader = new BufferedReader(new
>>> InputStreamReader(socket.getInputStream()), INPUT_BUFFER_SIZE);
>>>                 outputWriter = new PrintWriter(new BufferedWriter(new
>>> OutputStreamWriter(socket.getOutputStream()),
>>>                         OUTPUT_BUFFER_SIZE));
>>>             } catch (NoRouteToHostException nrthe) {
>>>                 System.out.println("host: " + url.getHost());
>>>                 nrthe.printStackTrace();
>>>             }
>>>         }
>>>
>>>         private void initConnection() throws IOException {
>>>             initSocket();
>>>             sendHeaders();
>>>         }
>>>
>>>         private void sendHeaders() {
>>>             String path = url.getPath();
>>>             StringBuffer outputBuffer = new StringBuffer();
>>>             outputBuffer.append("POST " + path + " HTTP/1.1" + DELIMITER);
>>>             outputBuffer.append("Host: " + url.getHost() + DELIMITER);
>>>             outputBuffer.append("User-Agent: CometTestApplet" + DELIMITER);
>>>             outputBuffer.append("Connection: keep-alive" + DELIMITER);
>>>             outputBuffer.append("Content-Type: text/plain" + DELIMITER);
>>>             outputBuffer.append("Transfer-Encoding: chunked" + DELIMITER);
>>>             outputBuffer.append(DELIMITER);
>>>             synchronized (outputWriter) {
>>>                 outputWriter.print(outputBuffer.toString());
>>>             }
>>>         }
>>>
>>>         public void send(String chunkData) throws IOException {
>>>             // chunk length field in hex
>>>             String hexChunkLength = Integer.toHexString(chunkData.length());
>>>
>>>             StringBuffer outputBuffer = new StringBuffer();
>>>             outputBuffer.append(hexChunkLength);
>>>             outputBuffer.append(DELIMITER);
>>>             outputBuffer.append(chunkData);
>>>             outputBuffer.append(DELIMITER);
>>>             synchronized (outputWriter) {
>>>                 outputWriter.print(outputBuffer.toString());
>>>                 outputWriter.flush();
>>>             }
>>>         }
>>>
>>>         private String readChunk() throws IOException {
>>>             StringBuffer inputBuffer = new StringBuffer();
>>>             String hexChunkSize = inputReader.readLine();
>>>             if (hexChunkSize != null) {
>>>                 int chunkSize = Integer.parseInt(hexChunkSize, 16);
>>>                 int charsRead = 0;
>>>
>>>                 char[] buf = new char[chunkSize];
>>>                 do {
>>>                     int n = inputReader.read(buf);
>>>                     charsRead += n;
>>>                     if (n > 0) {
>>>                         inputBuffer.append(new String(buf, 0, n));
>>>                     } else if (n < 0) {
>>>                         // occurs when connection is closed, often in response
>>>                         // to http session timeout from server
>>>                         throw new IOException("no bytes read");
>>>                     }
>>>                 } while (charsRead < chunkSize);
>>>                 // extra \r\n sent after chunk - part of protocol
>>>                 inputReader.readLine();
>>>             }
>>>             return inputBuffer.toString();
>>>         }
>>>
>>>         public String receive() throws IOException {
>>>             readHeaders();
>>>             return readChunk();
>>>         }
>>>
>>>         private void readHeaders() throws IOException {
>>>             String header;
>>>             while ((header = inputReader.readLine()) != null) {
>>>                 System.out.println("header: " + header);
>>>                 if (header.length() == 0) {
>>>                     break;
>>>                 }
>>>             }
>>>         }
>>>       ...
>>>     }
>>>
>>> SERVER
>>> ------
>>> public class CometTestServlet extends HttpServlet implements CometProcessor {
>>>     private static final long serialVersionUID = 5472498184127924791L;
>>>
>>>     public void event(CometEvent cometEvent) throws IOException,
>>> ServletException {
>>>         HttpServletRequest request = cometEvent.getHttpServletRequest();
>>>         HttpSession httpSession = request.getSession(true);
>>>         if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
>>>             cometEvent.setTimeout(3 * 60 * 60 * 1000); // 3 hours
>>>             // tell the http session not to timeout - will invalidate it on
>>>             // error or end
>>>             httpSession.setMaxInactiveInterval(-1);
>>>         } else if (cometEvent.getEventType() == CometEvent.EventType.ERROR) {
>>>             handleErrorEvent(cometEvent, httpSession);
>>>         } else if (cometEvent.getEventType() == CometEvent.EventType.END) {
>>>             close(cometEvent, httpSession);
>>>         } else if (cometEvent.getEventType() == CometEvent.EventType.READ) {
>>>             handleReadEvent(cometEvent);
>>>         }
>>>     }
>>>
>>>     protected void handleErrorEvent(CometEvent cometEvent, HttpSession
>>> httpSession) throws IOException {
>>>         if (cometEvent.getEventSubType() != CometEvent.EventSubType.TIMEOUT) {
>>>             close(cometEvent, httpSession);
>>>         }
>>>     }
>>>
>>>     private void close(CometEvent cometEvent, HttpSession httpSession)
>>> throws IOException {
>>>         cometEvent.close();
>>>         httpSession.invalidate();
>>>     }
>>>
>>>     private void handleReadEvent(CometEvent cometEvent) throws
>>> IOException, ServletException {
>>>         ServerCometChannel talker = new ServerCometChannel(cometEvent);
>>>         respond(talker);
>>>     }
>>>
>>>     private void respond(ServerCometChannel channel) throws IOException {
>>>         String clientMessage = channel.receive();
>>>
>>>         if (clientMessage != null && clientMessage.length() > 0) {
>>>             channel.send("comet succeeded");
>>>         }
>>>     }
>>>
>>>     private class ServerCometChannel {
>>>
>>>         private static final int OUTPUT_BUFFER_SIZE = 512;
>>>
>>>         private CometEvent cometEvent;
>>>
>>>         private InputStream inputStream;
>>>
>>>         private PrintWriter outputWriter;
>>>
>>>         public ServerCometChannel(CometEvent cometEvent) throws
>>> IOException, ServletException {
>>>             this.cometEvent = cometEvent;
>>>             inputStream = cometEvent.getHttpServletRequest().getInputStream();
>>>             OutputStream outputStream =
>>> cometEvent.getHttpServletResponse().getOutputStream();
>>>             this.outputWriter = new PrintWriter(new BufferedWriter(new
>>> OutputStreamWriter(outputStream),
>>>                     OUTPUT_BUFFER_SIZE));
>>>         }
>>>
>>>         private String receive() throws IOException {
>>>             StringBuffer buffer = new StringBuffer();
>>>             byte[] buf = new byte[512];
>>>             while (inputStream.available() > 0) {
>>>                 int n = inputStream.read(buf);
>>>                 if (n > 0) {
>>>                     buffer.append(new String(buf, 0, n));
>>>                 }
>>>             }
>>>             return buffer.toString();
>>>         }
>>>
>>>         public void send(String msg) {
>>>             synchronized (cometEvent.getHttpServletResponse()) {
>>>                 outputWriter.print(msg);
>>>                 outputWriter.flush();
>>>             }
>>>         }
>>>
>>>         public void close() throws IOException {
>>>             inputStream.close();
>>>             outputWriter.close();
>>>         }
>>>     }
>>>
>>> ---------------------------------------------------------------------
>>> To start a new topic, e-mail: users@tomcat.apache.org
>>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>>> For additional commands, e-mail: users-help@tomcat.apache.org
>>>
>>>
>>>
>>>
>>>       
>> ---------------------------------------------------------------------
>> To start a new topic, e-mail: users@tomcat.apache.org
>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>> For additional commands, e-mail: users-help@tomcat.apache.org
>>
>>
>>     
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>
>
>   


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: comet questions

Posted by Peter Warren <to...@gmail.com>.
Using the NIO connector: protocol="org.apache.coyote.http11.Http11NioProtocol".

I'll add response.flushBuffer() and see if that helps.

The tomcat version I was testing against was current with svn as of
last Friday.  I just updated and the only files that are new are:
catalina.policy
STATUS.txt
changelog.xml

Any ideas about the timeout setting or the comet error event without a subtype?

Thanks for your response!

Peter

On Jan 7, 2008 12:44 PM, Filip Hanik - Dev Lists <de...@hanik.com> wrote:
> what connector are you using?
> I would try to use response.flushBuffer when you wanna flush it out (ie
> after you've written to and flushed your stream).
>
> also, there have been some bug fixes, that you can get from SVN, or wait
> for 6.0.16 to come out
>
> Filip
>
>
> Peter Warren wrote:
> > I have some comet questions.  I'm using the tomcat 6.0.x trunk as of
> > last Friday.
> >
> > 1) My comet event timeout setting being honored.  How come?  I set the
> > timeout for 3 hours but a timeout event gets generated every 2
> > minutes.  If I inspect the comet event for which the timeout is
> > triggered, I see a setting for the request attribute of:
> > org.apache.tomcat.comet.timeout=10800000.
> >
> > I set it as follows:
> >
> >     public void event(CometEvent cometEvent) throws IOException,
> > ServletException {
> >       ...
> >         if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
> >           // COMET_TIMEOUT = 3 * 60 * 60 * 1000
> >             cometEvent.setTimeout(TimingConstants.COMET_TIMEOUT);
> >
> > Do I need to set something else as well?
> >
> > 2) Occasionally I'm getting a comet event of type ERROR without any
> > subtype (i.e. not TIMEOUT, CLIENT_DISCONNECT, etc.).  What does that
> > indicate?  I don't see any errors in my catalina log.
> >
> > 3) Reading the response from a comet servlet fails for one of my
> > client machines.  I wrote a simple test to check the problem.  This
> > test succeeds for many other users.  For the failing client, the
> > client request is received by the comet servlet, and the servlet's
> > response is written and flushed to the stream.  The client then simply
> > waits indefinitely trying to read the response.  The failing client is
> > a Windows XP machine.  Could anyone shed some light on why this might
> > be happening, or give me some clues as to how to debug?  Could it be a
> > firewall issue on the client end, a router issue on my end?
> >
> > The test is currently up at: http://www.seekspeak.com/test.html.  It
> > tests: a http connection to a normal servlet, then a comet connection
> > to a comet servlet using httpurlconnection, then a comet connection to
> > a comet servlet using a socket.  For the failing client, both comet
> > tests fail.
> >
> > Below is some of the test code for the raw socket test.
> >
> > Thanks for any help!
> >
> > Peter
> >
> > CLIENT
> > ------
> >     private void testCometConnection() throws IOException {
> >       ...
> >         URL url = new URL("http://www.seekspeak.com/CometTest");
> >         channel = new CometChannel(url);
> >         Thread testThread = new Thread() {
> >             public void run() {
> >                 try {
> >                     channel.send("test");
> >                     String received = channel.receive();
> >                     ...
> >                     }
> >                 } catch (IOException ioe) {
> >                     ioe.printStackTrace();
> >                 }
> >             }
> >         };
> >         testThread.start();
> >       ...
> >     }
> >
> >     private class CometChannel {
> >
> >         private static final int INPUT_BUFFER_SIZE = 512;
> >
> >         private static final int OUTPUT_BUFFER_SIZE = 512;
> >
> >         private static final String DELIMITER = "\r\n";
> >
> >         private URL url;
> >
> >         private BufferedReader inputReader;
> >
> >         private PrintWriter outputWriter;
> >
> >         private Socket socket;
> >
> >         public CometChannel(URL url) throws IOException {
> >             this.url = url;
> >             initConnection();
> >         }
> >
> >         private void initSocket() throws IOException {
> >             int port = url.getPort();
> >             port = (port < 0) ? url.getDefaultPort() : port;
> >             try {
> >                 socket = new Socket(url.getHost(), port);
> >                 socket.setKeepAlive(true);
> >                 inputReader = new BufferedReader(new
> > InputStreamReader(socket.getInputStream()), INPUT_BUFFER_SIZE);
> >                 outputWriter = new PrintWriter(new BufferedWriter(new
> > OutputStreamWriter(socket.getOutputStream()),
> >                         OUTPUT_BUFFER_SIZE));
> >             } catch (NoRouteToHostException nrthe) {
> >                 System.out.println("host: " + url.getHost());
> >                 nrthe.printStackTrace();
> >             }
> >         }
> >
> >         private void initConnection() throws IOException {
> >             initSocket();
> >             sendHeaders();
> >         }
> >
> >         private void sendHeaders() {
> >             String path = url.getPath();
> >             StringBuffer outputBuffer = new StringBuffer();
> >             outputBuffer.append("POST " + path + " HTTP/1.1" + DELIMITER);
> >             outputBuffer.append("Host: " + url.getHost() + DELIMITER);
> >             outputBuffer.append("User-Agent: CometTestApplet" + DELIMITER);
> >             outputBuffer.append("Connection: keep-alive" + DELIMITER);
> >             outputBuffer.append("Content-Type: text/plain" + DELIMITER);
> >             outputBuffer.append("Transfer-Encoding: chunked" + DELIMITER);
> >             outputBuffer.append(DELIMITER);
> >             synchronized (outputWriter) {
> >                 outputWriter.print(outputBuffer.toString());
> >             }
> >         }
> >
> >         public void send(String chunkData) throws IOException {
> >             // chunk length field in hex
> >             String hexChunkLength = Integer.toHexString(chunkData.length());
> >
> >             StringBuffer outputBuffer = new StringBuffer();
> >             outputBuffer.append(hexChunkLength);
> >             outputBuffer.append(DELIMITER);
> >             outputBuffer.append(chunkData);
> >             outputBuffer.append(DELIMITER);
> >             synchronized (outputWriter) {
> >                 outputWriter.print(outputBuffer.toString());
> >                 outputWriter.flush();
> >             }
> >         }
> >
> >         private String readChunk() throws IOException {
> >             StringBuffer inputBuffer = new StringBuffer();
> >             String hexChunkSize = inputReader.readLine();
> >             if (hexChunkSize != null) {
> >                 int chunkSize = Integer.parseInt(hexChunkSize, 16);
> >                 int charsRead = 0;
> >
> >                 char[] buf = new char[chunkSize];
> >                 do {
> >                     int n = inputReader.read(buf);
> >                     charsRead += n;
> >                     if (n > 0) {
> >                         inputBuffer.append(new String(buf, 0, n));
> >                     } else if (n < 0) {
> >                         // occurs when connection is closed, often in response
> >                         // to http session timeout from server
> >                         throw new IOException("no bytes read");
> >                     }
> >                 } while (charsRead < chunkSize);
> >                 // extra \r\n sent after chunk - part of protocol
> >                 inputReader.readLine();
> >             }
> >             return inputBuffer.toString();
> >         }
> >
> >         public String receive() throws IOException {
> >             readHeaders();
> >             return readChunk();
> >         }
> >
> >         private void readHeaders() throws IOException {
> >             String header;
> >             while ((header = inputReader.readLine()) != null) {
> >                 System.out.println("header: " + header);
> >                 if (header.length() == 0) {
> >                     break;
> >                 }
> >             }
> >         }
> >       ...
> >     }
> >
> > SERVER
> > ------
> > public class CometTestServlet extends HttpServlet implements CometProcessor {
> >     private static final long serialVersionUID = 5472498184127924791L;
> >
> >     public void event(CometEvent cometEvent) throws IOException,
> > ServletException {
> >         HttpServletRequest request = cometEvent.getHttpServletRequest();
> >         HttpSession httpSession = request.getSession(true);
> >         if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
> >             cometEvent.setTimeout(3 * 60 * 60 * 1000); // 3 hours
> >             // tell the http session not to timeout - will invalidate it on
> >             // error or end
> >             httpSession.setMaxInactiveInterval(-1);
> >         } else if (cometEvent.getEventType() == CometEvent.EventType.ERROR) {
> >             handleErrorEvent(cometEvent, httpSession);
> >         } else if (cometEvent.getEventType() == CometEvent.EventType.END) {
> >             close(cometEvent, httpSession);
> >         } else if (cometEvent.getEventType() == CometEvent.EventType.READ) {
> >             handleReadEvent(cometEvent);
> >         }
> >     }
> >
> >     protected void handleErrorEvent(CometEvent cometEvent, HttpSession
> > httpSession) throws IOException {
> >         if (cometEvent.getEventSubType() != CometEvent.EventSubType.TIMEOUT) {
> >             close(cometEvent, httpSession);
> >         }
> >     }
> >
> >     private void close(CometEvent cometEvent, HttpSession httpSession)
> > throws IOException {
> >         cometEvent.close();
> >         httpSession.invalidate();
> >     }
> >
> >     private void handleReadEvent(CometEvent cometEvent) throws
> > IOException, ServletException {
> >         ServerCometChannel talker = new ServerCometChannel(cometEvent);
> >         respond(talker);
> >     }
> >
> >     private void respond(ServerCometChannel channel) throws IOException {
> >         String clientMessage = channel.receive();
> >
> >         if (clientMessage != null && clientMessage.length() > 0) {
> >             channel.send("comet succeeded");
> >         }
> >     }
> >
> >     private class ServerCometChannel {
> >
> >         private static final int OUTPUT_BUFFER_SIZE = 512;
> >
> >         private CometEvent cometEvent;
> >
> >         private InputStream inputStream;
> >
> >         private PrintWriter outputWriter;
> >
> >         public ServerCometChannel(CometEvent cometEvent) throws
> > IOException, ServletException {
> >             this.cometEvent = cometEvent;
> >             inputStream = cometEvent.getHttpServletRequest().getInputStream();
> >             OutputStream outputStream =
> > cometEvent.getHttpServletResponse().getOutputStream();
> >             this.outputWriter = new PrintWriter(new BufferedWriter(new
> > OutputStreamWriter(outputStream),
> >                     OUTPUT_BUFFER_SIZE));
> >         }
> >
> >         private String receive() throws IOException {
> >             StringBuffer buffer = new StringBuffer();
> >             byte[] buf = new byte[512];
> >             while (inputStream.available() > 0) {
> >                 int n = inputStream.read(buf);
> >                 if (n > 0) {
> >                     buffer.append(new String(buf, 0, n));
> >                 }
> >             }
> >             return buffer.toString();
> >         }
> >
> >         public void send(String msg) {
> >             synchronized (cometEvent.getHttpServletResponse()) {
> >                 outputWriter.print(msg);
> >                 outputWriter.flush();
> >             }
> >         }
> >
> >         public void close() throws IOException {
> >             inputStream.close();
> >             outputWriter.close();
> >         }
> >     }
> >
> > ---------------------------------------------------------------------
> > To start a new topic, e-mail: users@tomcat.apache.org
> > To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> > For additional commands, e-mail: users-help@tomcat.apache.org
> >
> >
> >
> >
>
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: comet questions

Posted by Filip Hanik - Dev Lists <de...@hanik.com>.
what connector are you using?
I would try to use response.flushBuffer when you wanna flush it out (ie 
after you've written to and flushed your stream).

also, there have been some bug fixes, that you can get from SVN, or wait 
for 6.0.16 to come out

Filip

Peter Warren wrote:
> I have some comet questions.  I'm using the tomcat 6.0.x trunk as of
> last Friday.
>
> 1) My comet event timeout setting being honored.  How come?  I set the
> timeout for 3 hours but a timeout event gets generated every 2
> minutes.  If I inspect the comet event for which the timeout is
> triggered, I see a setting for the request attribute of:
> org.apache.tomcat.comet.timeout=10800000.
>
> I set it as follows:
>
>     public void event(CometEvent cometEvent) throws IOException,
> ServletException {
> 	...
>         if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
> 	    // COMET_TIMEOUT = 3 * 60 * 60 * 1000
>             cometEvent.setTimeout(TimingConstants.COMET_TIMEOUT);
>
> Do I need to set something else as well?
>
> 2) Occasionally I'm getting a comet event of type ERROR without any
> subtype (i.e. not TIMEOUT, CLIENT_DISCONNECT, etc.).  What does that
> indicate?  I don't see any errors in my catalina log.
>
> 3) Reading the response from a comet servlet fails for one of my
> client machines.  I wrote a simple test to check the problem.  This
> test succeeds for many other users.  For the failing client, the
> client request is received by the comet servlet, and the servlet's
> response is written and flushed to the stream.  The client then simply
> waits indefinitely trying to read the response.  The failing client is
> a Windows XP machine.  Could anyone shed some light on why this might
> be happening, or give me some clues as to how to debug?  Could it be a
> firewall issue on the client end, a router issue on my end?
>
> The test is currently up at: http://www.seekspeak.com/test.html.  It
> tests: a http connection to a normal servlet, then a comet connection
> to a comet servlet using httpurlconnection, then a comet connection to
> a comet servlet using a socket.  For the failing client, both comet
> tests fail.
>
> Below is some of the test code for the raw socket test.
>
> Thanks for any help!
>
> Peter
>
> CLIENT
> ------
>     private void testCometConnection() throws IOException {
> 	...
>         URL url = new URL("http://www.seekspeak.com/CometTest");
>         channel = new CometChannel(url);
>         Thread testThread = new Thread() {
>             public void run() {
>                 try {
>                     channel.send("test");
>                     String received = channel.receive();
>                     ...
>                     }
>                 } catch (IOException ioe) {
>                     ioe.printStackTrace();
>                 }
>             }
>         };
>         testThread.start();
> 	...
>     }
>
>     private class CometChannel {
>
>         private static final int INPUT_BUFFER_SIZE = 512;
>
>         private static final int OUTPUT_BUFFER_SIZE = 512;
>
>         private static final String DELIMITER = "\r\n";
>
>         private URL url;
>
>         private BufferedReader inputReader;
>
>         private PrintWriter outputWriter;
>
>         private Socket socket;
>
>         public CometChannel(URL url) throws IOException {
>             this.url = url;
>             initConnection();
>         }
>
>         private void initSocket() throws IOException {
>             int port = url.getPort();
>             port = (port < 0) ? url.getDefaultPort() : port;
>             try {
>                 socket = new Socket(url.getHost(), port);
>                 socket.setKeepAlive(true);
>                 inputReader = new BufferedReader(new
> InputStreamReader(socket.getInputStream()), INPUT_BUFFER_SIZE);
>                 outputWriter = new PrintWriter(new BufferedWriter(new
> OutputStreamWriter(socket.getOutputStream()),
>                         OUTPUT_BUFFER_SIZE));
>             } catch (NoRouteToHostException nrthe) {
>                 System.out.println("host: " + url.getHost());
>                 nrthe.printStackTrace();
>             }
>         }
>
>         private void initConnection() throws IOException {
>             initSocket();
>             sendHeaders();
>         }
>
>         private void sendHeaders() {
>             String path = url.getPath();
>             StringBuffer outputBuffer = new StringBuffer();
>             outputBuffer.append("POST " + path + " HTTP/1.1" + DELIMITER);
>             outputBuffer.append("Host: " + url.getHost() + DELIMITER);
>             outputBuffer.append("User-Agent: CometTestApplet" + DELIMITER);
>             outputBuffer.append("Connection: keep-alive" + DELIMITER);
>             outputBuffer.append("Content-Type: text/plain" + DELIMITER);
>             outputBuffer.append("Transfer-Encoding: chunked" + DELIMITER);
>             outputBuffer.append(DELIMITER);
>             synchronized (outputWriter) {
>                 outputWriter.print(outputBuffer.toString());
>             }
>         }
>
>         public void send(String chunkData) throws IOException {
>             // chunk length field in hex
>             String hexChunkLength = Integer.toHexString(chunkData.length());
>
>             StringBuffer outputBuffer = new StringBuffer();
>             outputBuffer.append(hexChunkLength);
>             outputBuffer.append(DELIMITER);
>             outputBuffer.append(chunkData);
>             outputBuffer.append(DELIMITER);
>             synchronized (outputWriter) {
>                 outputWriter.print(outputBuffer.toString());
>                 outputWriter.flush();
>             }
>         }
>
>         private String readChunk() throws IOException {
>             StringBuffer inputBuffer = new StringBuffer();
>             String hexChunkSize = inputReader.readLine();
>             if (hexChunkSize != null) {
>                 int chunkSize = Integer.parseInt(hexChunkSize, 16);
>                 int charsRead = 0;
>
>                 char[] buf = new char[chunkSize];
>                 do {
>                     int n = inputReader.read(buf);
>                     charsRead += n;
>                     if (n > 0) {
>                         inputBuffer.append(new String(buf, 0, n));
>                     } else if (n < 0) {
>                         // occurs when connection is closed, often in response
>                         // to http session timeout from server
>                         throw new IOException("no bytes read");
>                     }
>                 } while (charsRead < chunkSize);
>                 // extra \r\n sent after chunk - part of protocol
>                 inputReader.readLine();
>             }
>             return inputBuffer.toString();
>         }
>
>         public String receive() throws IOException {
>             readHeaders();
>             return readChunk();
>         }
>
>         private void readHeaders() throws IOException {
>             String header;
>             while ((header = inputReader.readLine()) != null) {
>                 System.out.println("header: " + header);
>                 if (header.length() == 0) {
>                     break;
>                 }
>             }
>         }
> 	...
>     }
>
> SERVER
> ------
> public class CometTestServlet extends HttpServlet implements CometProcessor {
>     private static final long serialVersionUID = 5472498184127924791L;
>
>     public void event(CometEvent cometEvent) throws IOException,
> ServletException {
>         HttpServletRequest request = cometEvent.getHttpServletRequest();
>         HttpSession httpSession = request.getSession(true);
>         if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
>             cometEvent.setTimeout(3 * 60 * 60 * 1000); // 3 hours
>             // tell the http session not to timeout - will invalidate it on
>             // error or end
>             httpSession.setMaxInactiveInterval(-1);
>         } else if (cometEvent.getEventType() == CometEvent.EventType.ERROR) {
>             handleErrorEvent(cometEvent, httpSession);
>         } else if (cometEvent.getEventType() == CometEvent.EventType.END) {
>             close(cometEvent, httpSession);
>         } else if (cometEvent.getEventType() == CometEvent.EventType.READ) {
>             handleReadEvent(cometEvent);
>         }
>     }
>
>     protected void handleErrorEvent(CometEvent cometEvent, HttpSession
> httpSession) throws IOException {
>         if (cometEvent.getEventSubType() != CometEvent.EventSubType.TIMEOUT) {
>             close(cometEvent, httpSession);
>         }
>     }
>
>     private void close(CometEvent cometEvent, HttpSession httpSession)
> throws IOException {
>         cometEvent.close();
>         httpSession.invalidate();
>     }
>
>     private void handleReadEvent(CometEvent cometEvent) throws
> IOException, ServletException {
>         ServerCometChannel talker = new ServerCometChannel(cometEvent);
>         respond(talker);
>     }
>
>     private void respond(ServerCometChannel channel) throws IOException {
>         String clientMessage = channel.receive();
>
>         if (clientMessage != null && clientMessage.length() > 0) {
>             channel.send("comet succeeded");
>         }
>     }
>
>     private class ServerCometChannel {
>
>         private static final int OUTPUT_BUFFER_SIZE = 512;
>
>         private CometEvent cometEvent;
>
>         private InputStream inputStream;
>
>         private PrintWriter outputWriter;
>
>         public ServerCometChannel(CometEvent cometEvent) throws
> IOException, ServletException {
>             this.cometEvent = cometEvent;
>             inputStream = cometEvent.getHttpServletRequest().getInputStream();
>             OutputStream outputStream =
> cometEvent.getHttpServletResponse().getOutputStream();
>             this.outputWriter = new PrintWriter(new BufferedWriter(new
> OutputStreamWriter(outputStream),
>                     OUTPUT_BUFFER_SIZE));
>         }
>
>         private String receive() throws IOException {
>             StringBuffer buffer = new StringBuffer();
>             byte[] buf = new byte[512];
>             while (inputStream.available() > 0) {
>                 int n = inputStream.read(buf);
>                 if (n > 0) {
>                     buffer.append(new String(buf, 0, n));
>                 }
>             }
>             return buffer.toString();
>         }
>
>         public void send(String msg) {
>             synchronized (cometEvent.getHttpServletResponse()) {
>                 outputWriter.print(msg);
>                 outputWriter.flush();
>             }
>         }
>
>         public void close() throws IOException {
>             inputStream.close();
>             outputWriter.close();
>         }
>     }
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>
>
>   


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org