I doubt it works properly with the HttpUrlConnection, its better if you use a socket connection, as you have no idea how the underlying implementation works in HttpUrlConnection

Filip

Peter Warren wrote:
Hi Filip,

Somehow I missed your response a while back.  Below are two test clients
and one comet servlet.  One client works, and the other doesn't.  I
found out the failing client doesn't work because HttpURLConnection
doesn't seem to allow writing to the output stream after the input
stream has been requested (or at least I haven't figured out how to
allow it).  On the other hand, Filip cautioned me against using the
client that works because it re-sends http headers with each request,
which could potentially get received as data by the comet servlet.
So... is there a way for me to use a single HttpURLConnection and be
able to read and write multiple times on its input and output streams? I tried setting Transfer-Encoding to chunked, but couldn't get it to
make a difference.  I'd like to use HttpURLConnection instead of raw
sockets to avoid having to manually handle the headers, redirects,
proxies, etc.  I realize this question is more java api specific than
tomcat comet specific, but since many comet users might like to use
HttpURLConnection, I thought it was still relevant here.

Thanks for any help,
Peter

### CometTestClient1.java - this test hangs since 2nd output on
HttpURLConnection doesn't get sent ###

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;

public class CometTestClient1 {

    private HttpURLConnection urlConn;

    private PrintWriter out;

    private URL url = new URL("http://127.0.0.1/CometTest";);

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

    public CometTestClient1() throws IOException {
        initConnection();
    }

    private void initConnection() throws IOException {
        urlConn = (HttpURLConnection) url.openConnection();
        urlConn.setDoInput(true);
        urlConn.setDoOutput(true);
        urlConn.connect();
        out = new PrintWriter(urlConn.getOutputStream());
    }

    public void test() throws IOException {
        out.println("test 1");
        out.flush();

        String line = read(urlConn.getInputStream());
        System.out.println(line);

        // next line never gets sent out -- presumably because the url
connection
        // doesn't allow output after getInputStream has been called
        out.println("test 2");
        out.flush();

        line = read(urlConn.getInputStream());
        System.out.println(line);

        out.close();
        urlConn.disconnect();
    }

    private String read(InputStream is) throws IOException {
        StringBuffer inputBuffer = new StringBuffer();
        byte[] buf = new byte[512];
        do {
            int n = is.read(buf); // can throw an IOException
            if (n > 0) {
                inputBuffer.append(new String(buf, 0, n));
            } else if (n < 0) {
                return ("read error");
            }
        } while (is.available() > 0);
        return inputBuffer.toString();
    }
}

### CometTestClient2.java - works but sends new http headers for each
client output ###

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;

public class CometTestClient2 {

    private HttpURLConnection urlConn;

    private PrintWriter out;

    private URL url = new URL("http://127.0.0.1/CometTest";);

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

    public CometTestClient2() throws IOException {
        initConnection();
    }

    private void initConnection() throws IOException {
        urlConn = (HttpURLConnection) url.openConnection();
        urlConn.setDoInput(true);
        urlConn.setDoOutput(true);
        urlConn.connect();
        out = new PrintWriter(urlConn.getOutputStream());
    }

    public void test() throws IOException {
        out.println("test 1");
        out.flush();

        BufferedReader in = new BufferedReader(new
InputStreamReader(urlConn.getInputStream()));

        String line = in.readLine();
        System.out.println(line);

        initConnection();
        out.println("test 2");
        out.flush();

        in = new BufferedReader(new
InputStreamReader(urlConn.getInputStream()));

        line = in.readLine();
        System.out.println(line);

        out.close();
        urlConn.disconnect();
    }
}

### CometTestServlet ###

import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.catalina.CometEvent;
import org.apache.catalina.CometProcessor;

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();
        HttpServletResponse response = cometEvent.getHttpServletResponse();
        // don't want timeout events
        cometEvent.setTimeout(1000000);
        if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
            log("Begin for session: " + request.getSession(true).getId());
            respond(request, response);
        } else if (cometEvent.getEventType() ==
CometEvent.EventType.ERROR) {
            log("Error for session: " + request.getSession(true).getId()
+ ", " + cometEvent.getEventSubType());
            cometEvent.close();
        } else if (cometEvent.getEventType() == CometEvent.EventType.END) {
            log("End for session: " + request.getSession(true).getId());
            cometEvent.close();
        } else if (cometEvent.getEventType() == CometEvent.EventType.READ) {
            log("Read for session: " + request.getSession(true).getId());
            respond(request, response);
        }
    }

    private void respond(HttpServletRequest request, HttpServletResponse
response) throws IOException {
        String clientMessage = read(request);
        if (clientMessage != null && clientMessage.length() > 0) {
            response.getWriter().println(clientMessage);
            response.getWriter().flush();
        }
    }

    private String read(HttpServletRequest request) throws IOException {
        InputStream is = request.getInputStream();
        StringBuffer inputBuffer = new StringBuffer();
        byte[] buf = new byte[512];
        do {
            int n = is.read(buf); // can throw an IOException
            if (n > 0) {
                inputBuffer.append(new String(buf, 0, n));
                log("Read " + n + " bytes: " + new String(buf, 0, n) + "
for session: "
                        + request.getSession(true).getId());
            } else if (n < 0) {
                log("comet read error");
            }
        } while (is.available() > 0);
        return inputBuffer.toString();
    }
}

Filip Hanik - Dev Lists wrote:
why don't you make your test available, I'll run it through

Filip

Peter Warren wrote:
Yes, I'm using the NIO connector.  Here is the config line from my
server.xml:

    <Connector port="80"
protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150"
connectionTimeout="20000" keepAliveTimeout="120000"
maxKeepAliveRequests="-1" acceptorThreadCount="2" redirectPort="8443" />

Are there any other configuration options I need to set?

Peter

Filip Hanik - Dev Lists wrote:
and you are using the APR or the NIO connector right?

Filip

Peter Warren wrote:
Thanks for the suggestion.  I changed the comet test servlet to read
directly from the input stream as shown in the advanced io
example.  I'm
still seeing the same behavior.  No comet read event gets generated on
the server, only the begin event which contains the client's first
message.  The client then sends its second message and blocks waiting
for the server.  No events are generated on the server in response to
the client's second message.  Any other tips for me?

Thanks,
Peter

from the CometTestServlet:

    public void event(CometEvent cometEvent) throws IOException,
ServletException {
    ...
        if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
            log("Begin for session: " +
request.getSession(true).getId());
            String clientMessage = read(request);
            if (clientMessage != null && clientMessage.length() > 0) {
                response.getWriter().println(clientMessage);
                response.getWriter().flush();
            }
        }
    ...

    private String read(HttpServletRequest request) throws
IOException {
        InputStream is = request.getInputStream();
        StringBuffer inputBuffer = new StringBuffer();
        byte[] buf = new byte[512];
        do {
            int n = is.read(buf); // can throw an IOException
            if (n > 0) {
                inputBuffer.append(new String(buf, 0, n));
                log("Read " + n + " bytes: " + new String(buf, 0,
n) + "
for session: "
                        + request.getSession(true).getId());
            } else if (n < 0) {
                log("comet read error");
            }
        } while (is.available() > 0);
        return inputBuffer.toString();
    }

from the CometTestClient:

    public void test() throws IOException {
        out.println("test 1");
        out.flush();

        String line = read(urlConn.getInputStream());
        System.out.println(line);

        out.println("test 2");
        out.flush();

        line = read(urlConn.getInputStream());
        System.out.println(line);

        out.close();
        urlConn.disconnect();
    }

    private String read(InputStream is) throws IOException {
        StringBuffer inputBuffer = new StringBuffer();
        byte[] buf = new byte[512];
        do {
            int n = is.read(buf); // can throw an IOException
            if (n > 0) {
                inputBuffer.append(new String(buf, 0, n));
            } else if (n < 0) {
                return ("read error");
            }
        } while (is.available() > 0);
        return inputBuffer.toString();
    }

Filip Hanik - Dev Lists wrote:
take a look at the documentation, the way you are reading it is
incorrect.
you need to take advantage of the available() method

Filip

Peter Warren wrote:
My BEGIN block in my comet servlet now looks like the code below
(added
a while loop to read until the buffer is empty).  Is that what
you had
in mind?  The buffer in the BEGIN event only contains the client's
first
message.  Am I not emptying the buffer correctly?  Although, I
wouldn't
expect the buffer to contain the client's second message since the
client blocks for an ack from the server before sending its second
message.  Any other thoughts on what happens to the client's second
message and why no READ event is generated?

Thanks for your help,
Peter

        if (cometEvent.getEventType() ==
CometEvent.EventType.BEGIN) {
            log("Begin for session: " +
request.getSession(true).getId());
            BufferedReader reader =
cometEvent.getHttpServletRequest().getReader();
            String line = null;
            while ((line = reader.readLine()) != null) {
                log("servlet received: " + line);
cometEvent.getHttpServletResponse().getWriter().println("servlet
received: " + line);
cometEvent.getHttpServletResponse().getWriter().flush();
            }
        }

Filip Hanik wrote:

it could be because the data from the request already came in with
the
request.
when the BEGIN happens, perform the actions as if there was a
READ as
well, ie, empty out the buffer.
Filip
Peter Warren wrote:
The following client code generates a comet BEGIN event on the
server
but not a subsequent READ event, as I was expecting.  How come?
Is my
code wrong?  Are my expectations wrong?  See sequence of events
commented in code below.

    // client test method that sends messages to server and
listens for
responses
    public void test() throws IOException {
        out.println("test 1");
        out.flush();

        // server receives client's message, generates a BEGIN
event,
and sends response to client

        in = new BufferedReader(new
InputStreamReader(urlConn.getInputStream()));
        System.out.println(in.readLine());

        // client receives server's response and prints it

        out.println("test 2");
        out.flush();

        System.out.println(in.readLine());

        // client code blocks here waiting for server response.
        // server never generates a READ event.  How come?
        // Does the HttpURLConnection (see full code below) need
to be
set up differently?
        // Am I using the PrintWriter incorrectly when sending
to the
comet servlet?

        out.close();
        urlConn.disconnect();
    }

Thanks for any help,
Peter

-- system --

using:
tomcat 6.0.13 on windows xp sp 2
java 1.6.0_01

-- test client & comet servlet source below --

## begin test client ##

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;

public class CometTestClient {

    private HttpURLConnection urlConn;

    private PrintWriter out;

    private BufferedReader in;

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

    public CometTestClient() throws IOException {
        initConnection();
    }

    private void initConnection() throws IOException {
        URL url = new URL("http://127.0.0.1/CometTest";);
        urlConn = (HttpURLConnection) url.openConnection();
        urlConn.setDoInput(true);
        urlConn.setDoOutput(true);
        urlConn.connect();
        out = new PrintWriter(urlConn.getOutputStream());
    }

    public void test() throws IOException {
        out.println("test 1");
        out.flush();

        in = new BufferedReader(new
InputStreamReader(urlConn.getInputStream()));
        System.out.println(in.readLine());

        out.println("test 2");
        out.flush();

        System.out.println(in.readLine());

        out.close();
        urlConn.disconnect();
    }
}

## end test client ##

## begin comet servlet ##

import java.io.BufferedReader;
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;

import org.apache.catalina.CometEvent;
import org.apache.catalina.CometProcessor;

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();
        // don't want timeout events
        cometEvent.setTimeout(1000000);
        if (cometEvent.getEventType() ==
CometEvent.EventType.BEGIN) {
            log("Begin for session: " +
request.getSession(true).getId());
            BufferedReader reader =
cometEvent.getHttpServletRequest().getReader();
            String line = reader.readLine();
            if (line != null) {
                log("servlet received: " + line);
cometEvent.getHttpServletResponse().getWriter().println("servlet
received: " + line);
cometEvent.getHttpServletResponse().getWriter().flush();
            } else {
                cometEvent.close();
            }
        } else if (cometEvent.getEventType() ==
CometEvent.EventType.ERROR) {
            log("Error for session: " +
request.getSession(true).getId()
+ ", " + cometEvent.getEventSubType());
            cometEvent.close();
        } else if (cometEvent.getEventType() ==
CometEvent.EventType.END) {
            log("End for session: " +
request.getSession(true).getId());
            cometEvent.close();
        } else if (cometEvent.getEventType() ==
CometEvent.EventType.READ) {
            log("Read for session: " +
request.getSession(true).getId());
            BufferedReader reader =
cometEvent.getHttpServletRequest().getReader();
            String line = reader.readLine();
            if (line != null) {
cometEvent.getHttpServletResponse().getWriter().println("servlet
received: " + line);
            } else {
                cometEvent.close();
            }
        }
    }
}

## end comet servlet ##

---------------------------------------------------------------------

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