I'll take a look at this for you!

Filip

Peter Warren wrote:
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]





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

Reply via email to