> as I mentioned, the "last chunk" doesn't generate an END event, I tried > it locally. of course against 6.0.x trunk.
I played around a bit because I was definitely getting an END event and found: Sending 0crlf does not generate and END event. However sending 0crlfcrlf, which is what HttpURLConnection does, does generate an END (or sometimes a read error - see below...) Looking at the http spec, it seems like 0crlfcrlf is actually the proper way to terminate the chunk body: Chunked-Body = *chunk last-chunk trailer CRLF last-chunk = 1*("0") [ chunk-extension ] CRLF Am I reading that correctly? Note about END and read error: When running both the client and the server locally (i.e. little latency), sending 0crlfcrlf would sometimes generate a read error (i.e. inputStream.isAvailable() > 0 would be true and then number of bytes read would be < 0) and sometimes an END event. I tried with both sockets and HttpURLConnection and saw similar behavior. However when using HttpURLConnection I could add a delay of 50 millis. and guarantee that I always got an end event (see code below). I am using the latest 6.0.x trunk updated locally today. Peter CLIENT CODE =========== URL url = new URL("http://www.seekspeak.com/CometTest"); HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); urlConn.setRequestMethod("POST"); urlConn.setChunkedStreamingMode(-1); // use default chunk length urlConn.setReadTimeout(0); urlConn.setDoInput(true); urlConn.setDoOutput(true); urlConn.connect(); PrintWriter out = new PrintWriter(urlConn.getOutputStream(), true); out.print("test"); out.flush(); try { // sleep to guarantee an END event - remove this sleep to get read error Thread.sleep(50); } catch (InterruptedException ie) { // do nothing } urlConn.getInputStream(); COMET SERVLET CODE: ============= public void event(CometEvent cometEvent) throws IOException, ServletException { System.out.println("event: " + cometEvent.getEventType() + ", subtype: " + cometEvent.getEventSubType()); if (cometEvent.getEventType() == CometEvent.EventType.ERROR) { cometEvent.close(); } else if (cometEvent.getEventType() == CometEvent.EventType.END) { cometEvent.close(); } else if (cometEvent.getEventType() == CometEvent.EventType.READ) { HttpServletRequest request = cometEvent.getHttpServletRequest(); InputStream inputStream = request.getInputStream(); byte[] buf = new byte[512]; do { int n = inputStream.read(buf); // can throw an IOException if (n > 0) { System.out.println("Read " + n + " bytes: " + new String(buf, 0, n) + " for session: " + request.getSession(true).getId()); } else if (n < 0) { System.out.println("read error"); return; } } while (inputStream.available() > 0); } } On Jan 21, 2008 11:53 AM, Filip Hanik - Dev Lists <[EMAIL PROTECTED]> wrote: > answers inline > > Peter Warren wrote: > > First off, thanks for your responses. The contributors to this list > > are extremely responsive, patient, and helpful, and I really > > appreciate it! > > > > Hmm, in your test case did you set the HttpURLConnection to use > > chunked transfers (setChunkedStreamingMode(...))? I find if I use > > chunked transfers, the HttpURLConnection sends a "last chunk" message > > upon reading input from the server, which generates a comet END event > > on the server. If I don't use chunked transfers, no END event is > > generated because no "last chunk" is sent by the client. > > > as I mentioned, the "last chunk" doesn't generate an END event, I tried > it locally. of course against 6.0.x trunk. > > Which brings up an option I never considered: will a comet servlet > > function properly with non-chunked transfer (i.e. no transfer-coding > > header)? It seems to. > > > yes, it can, just send a very large content-length header > > Lastly, I'm still a little confused about requiring the comet event to > > be closed on an END event. Doesn't this mean that tomcat comet can't > > handle pipelined requests? If a client sends 2 pipelined requests, it > > will send a "last chunk" to indicate the end of the first request. > > This "last chunk" will generate an END event on the server, which then > > requires the connection to be closed. After the comet event is closed > > the server cannot send a response to the client. > > > pipelined requests are not defined by the HTTP spec for POST methods, > only for GET > assuming the pipelining you are talking about is true pipelining :) > if you just mean, next request, then yes, tomcat handles that just fine, > and that is why you have to call event.close() > > The END event docs indicate that pipelined request will generate an > > END event: ...End will also be called when data is available and the > > end of file is reached on the request input (this usually indicates > > the client has pipelined a request). > > > depends on what you mean by pipeline, see above > > > Thanks, > > Peter > > > > On Jan 20, 2008 8:15 PM, Filip Hanik - Dev Lists <[EMAIL PROTECTED]> wrote: > > > >> now I get it. I just ran through a test case, and an END event was not > >> thrown just because there was an end chunk. > >> the response is very much still open at that point > >> > >> > >> Filip > >> > >> Peter Warren wrote: > >> > >>> What java.net.HttpURLConnection has to do with Tomcat and comet is > >>> that HttpURLConnection is Java's implementation of an http client and > >>> will likely be used by people developing comet apps for Tomcat. In my > >>> case, I want to use it because I can't use raw sockets on my applet > >>> client due to permission problems when trying to use sockets behind a > >>> proxy. > >>> > >>> I understand that asynchronous writes are possible, but they're not > >>> when using HttpURLConnection because HttpURLConnection sends a "last > >>> chunk" message when it's done with its request. "Last chunk" > >>> generates a comet end event, which then requires that the connection > >>> to the client be closed. > >>> > >>> I guess I don't understand why tomcat needs to close the connection > >>> after an END event. It seems to me that the "last chunk" message from > >>> the client simply indicates that the client is done sending its > >>> request. Why does the server need to close the connection when the > >>> client finishes its request? > >>> > >>> Peter > >>> > >>> On Jan 19, 2008 6:01 PM, Filip Hanik - Dev Lists <[EMAIL PROTECTED]> > >>> wrote: > >>> > >>> > >>>> I'm not sure what HttpURLConnection has to do with Tomcat or comet. > >>>> and yes, asynchronous writes are possible, just not after the END or > >>>> ERROR events have been issued > >>>> > >>>> Filip > >>>> > >>>> > >>>> Peter Warren wrote: > >>>> > >>>> > >>>>> Does that mean that HttpURLConnection cannot be used for comet > >>>>> requests with asynchronous (i.e. delayed) responses? > >>>>> > >>>>> It would seem so to me since HttpURLConnection always sends an END > >>>>> message before reading from the server and since the server can no > >>>>> longer write to the client after closing the comet event. Am I > >>>>> missing something? Is there a way to write to the client after the > >>>>> comet event is closed? > >>>>> > >>>>> Would you consider it a bug that HttpURLConnection is implemented that > >>>>> way? > >>>>> > >>>>> Peter > >>>>> > >>>>> On Jan 18, 2008 9:21 PM, Filip Hanik - Dev Lists <[EMAIL PROTECTED]> > >>>>> wrote: > >>>>> > >>>>> > >>>>> > >>>>>> during end and error, you MUST close the Comet event > >>>>>> > >>>>>> Filip > >>>>>> > >>>>>> > >>>>>> Peter Warren wrote: > >>>>>> > >>>>>> > >>>>>> > >>>>>>> What do I do to make the END event stop repeating? I don't want to > >>>>>>> close the CometEvent yet because the server is waiting for data to > >>>>>>> send to the client. If I don't close the comet event, the END event > >>>>>>> repeats incessantly. > >>>>>>> > >>>>>>> I'm using an unsigned applet as a comet client. To accommodate > >>>>>>> proxies, I've had to change my comet client to use HttpURLConnection > >>>>>>> instead of Sockets. (Accessing ProxySelector from an applet to create > >>>>>>> a socket with a proxy generates an AccessControlException.) > >>>>>>> > >>>>>>> HttpURLConnection unfortunately sends a 0crlf when its input stream is > >>>>>>> retrieved for reading. This generates a Comet END event. Short of > >>>>>>> closing the comet event, how can I make the server stop notifying me > >>>>>>> of END events? I can't close the comet event because I want to hold > >>>>>>> onto the comet output stream for use later to send data to the client. > >>>>>>> > >>>>>>> >From the comet docs: > >>>>>>> EventType.END: End may be called to end the processing of the request. > >>>>>>> Fields that have been initialized in the begin method should be reset. > >>>>>>> After this event has been processed, the request and response objects, > >>>>>>> as well as all their dependent objects will be recycled and used to > >>>>>>> process other requests. End will also be called when data is available > >>>>>>> and the end of file is reached on the request input (this usually > >>>>>>> indicates the client has pipelined a request). > >>>>>>> > >>>>>>> This seems to indicate that even if I could get the END event to go > >>>>>>> away quietly, the comet event's output stream might no longer be > >>>>>>> usable anyway. > >>>>>>> > >>>>>>> It seems to me I have 3 options: > >>>>>>> 1) figure out how to make the comet END event stop repeating and hope > >>>>>>> it's output stream still works > >>>>>>> 2) figure out how to keep HttpURLConnection from sending 0crlf (don't > >>>>>>> know if that can be done) > >>>>>>> 2) use sockets with ProxySelector (which requires signing my applet > >>>>>>> and getting users to grant it privileges) > >>>>>>> > >>>>>>> Thanks, > >>>>>>> Peter > >>>>>>> > >>>>>>> --------------------------------------------------------------------- > >>>>>>> To start a new topic, e-mail: users@tomcat.apache.org > >>>>>>> To unsubscribe, e-mail: [EMAIL PROTECTED] > >>>>>>> For additional commands, e-mail: [EMAIL PROTECTED] > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>> --------------------------------------------------------------------- > >>>>>> To start a new topic, e-mail: users@tomcat.apache.org > >>>>>> To unsubscribe, e-mail: [EMAIL PROTECTED] > >>>>>> For additional commands, e-mail: [EMAIL PROTECTED] > >>>>>> > >>>>>> > >>>>>> > >>>>>> > >>>>>> > >>>>> --------------------------------------------------------------------- > >>>>> To start a new topic, e-mail: users@tomcat.apache.org > >>>>> To unsubscribe, e-mail: [EMAIL PROTECTED] > >>>>> For additional commands, e-mail: [EMAIL PROTECTED] > >>>>> > >>>>> > >>>>> > >>>>> > >>>>> > >>>>> > >>>> --------------------------------------------------------------------- > >>>> To start a new topic, e-mail: users@tomcat.apache.org > >>>> To unsubscribe, e-mail: [EMAIL PROTECTED] > >>>> For additional commands, e-mail: [EMAIL PROTECTED] > >>>> > >>>> > >>>> > >>>> > >>> --------------------------------------------------------------------- > >>> To start a new topic, e-mail: users@tomcat.apache.org > >>> To unsubscribe, e-mail: [EMAIL PROTECTED] > >>> For additional commands, e-mail: [EMAIL PROTECTED] > >>> > >>> > >>> > >>> > >>> > >> --------------------------------------------------------------------- > >> To start a new topic, e-mail: users@tomcat.apache.org > >> To unsubscribe, e-mail: [EMAIL PROTECTED] > >> For additional commands, e-mail: [EMAIL PROTECTED] > >> > >> > >> > > > > --------------------------------------------------------------------- > > To start a new topic, e-mail: users@tomcat.apache.org > > To unsubscribe, e-mail: [EMAIL PROTECTED] > > For additional commands, e-mail: [EMAIL PROTECTED] > > > > > > > > > > > --------------------------------------------------------------------- > To start a new topic, e-mail: users@tomcat.apache.org > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > --------------------------------------------------------------------- To start a new topic, e-mail: users@tomcat.apache.org To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]