Return-Path: Delivered-To: apmail-tomcat-users-archive@www.apache.org Received: (qmail 50133 invoked from network); 7 Jan 2008 21:47:39 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 7 Jan 2008 21:47:39 -0000 Received: (qmail 86977 invoked by uid 500); 7 Jan 2008 21:47:16 -0000 Delivered-To: apmail-tomcat-users-archive@tomcat.apache.org Received: (qmail 86949 invoked by uid 500); 7 Jan 2008 21:47:15 -0000 Mailing-List: contact users-help@tomcat.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Tomcat Users List" Delivered-To: mailing list users@tomcat.apache.org Received: (qmail 86938 invoked by uid 99); 7 Jan 2008 21:47:15 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 07 Jan 2008 13:47:15 -0800 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of tomcat.subscription@gmail.com designates 64.233.162.233 as permitted sender) Received: from [64.233.162.233] (HELO nz-out-0506.google.com) (64.233.162.233) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 07 Jan 2008 21:46:51 +0000 Received: by nz-out-0506.google.com with SMTP id z6so1534215nzd.9 for ; Mon, 07 Jan 2008 13:46:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:to:subject:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; bh=WWS+PRuNoRvPWHsmsSkuXED2OJ18ouXSJrJMN/pSBrI=; b=StwRj1w0bHqfKiR0Ru8+Ofi9Lt7hmZVpokwKY3L/wcR2cwxsQBlefGt/dB+9QRXzYyWjoj/UfceE2jr4h2cQz1X3SSiwsiLNiAbV5HjEdKzW01Jkg71rfLAYMf4pNg2mX6qfMPxvzfsWkh8qJf5g2EPeWPDCnWacVHO0BAILTWE= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=hiXjqbi49AnELkFxWjFncL2kL5rFytfnbaZKW5kAagqcf3bTEy6qagf8I01jJclDEaZABslB07lH1x/4ZMYQsPkETQYpWZ8KdvxEG187n2RM2iSd2DnOU/QOaHRPNAY2AtEnlTJ6LPs/DQQldxvOjw7ZBxsF+wCWctcTSzFH4Eo= Received: by 10.143.162.8 with SMTP id p8mr2766960wfo.49.1199742414752; Mon, 07 Jan 2008 13:46:54 -0800 (PST) Received: by 10.142.86.2 with HTTP; Mon, 7 Jan 2008 13:46:54 -0800 (PST) Message-ID: <176a7eb80801071346q5a76c326q499d3bfdc1d88095@mail.gmail.com> Date: Mon, 7 Jan 2008 13:46:54 -0800 From: "Peter Warren" To: "Tomcat Users List" Subject: Re: comet questions In-Reply-To: <47828F23.8090104@hanik.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <176a7eb80801071115j633d328dre5e63ae3b5a2ac89@mail.gmail.com> <47828F23.8090104@hanik.com> X-Virus-Checked: Checked by ClamAV on apache.org 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 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