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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]