CloseableHttpResponse closes socket while streaming

24 views Asked by At

I am trying to read an http stream using Apache's CloseableHttpClient. For regular URLs that return a single response, this has been working well, but I haven't had luck with streaming responses. My code runs in a thread. I would like to call the grabUrl() method to return an input stream, then do the reading/parsing in run().

Right now the code runs, but the socket closes after just a few bytes are read.

> java.net.SocketException: Socket closed
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:171)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at org.apache.hc.core5.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:149)
    at org.apache.hc.core5.http.impl.io.SessionInputBufferImpl.read(SessionInputBufferImpl.java:203)
    at org.apache.hc.core5.http.impl.io.IdentityInputStream.read(IdentityInputStream.java:99)
    at org.apache.hc.core5.http.io.EofSensorInputStream.read(EofSensorInputStream.java:135)
    at org.apache.hc.core5.http.io.EofSensorInputStream.read(EofSensorInputStream.java:148)
    at org.example.R300NotificationsReader.run(R300NotificationsReader.java:114)
10:53:28 AM: Execution finished ':Main.main()'.

My suspicion is that either I'm doing something to close the socket, a local variable is getting deleted when I leave the function, or I just plain have the wrong http client for the job. I have the same function working using Python's Requests module, but I need to recreate it in Java, and this is my first time trying to work with HTTP endpoints in Java.

This is my grabUrl() function:

public InputStream grabUrl(String url, int messageID) {
    ClassicHttpRequest httpGet = null;
    try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
        if (url.equals(notificationNegotiateUrl)) {
            httpGet = ClassicRequestBuilder.get(R300Utils.addParameters(url, messageID)).build();
        }
        else {
            httpGet = ClassicRequestBuilder.get(R300Utils.addParametersWithToken(url, messageID, tid)).build();
        }
        CloseableHttpResponse response = httpClient.execute(httpGet);
        System.out.println(response.getCode() + " " + response.getReasonPhrase());
        if (response.getCode() >= 200 && response.getCode() < 300) {
            // Get the response entity
            HttpEntity entity = response.getEntity();

            if (entity != null) {
                // Return the input stream from the response entity
                return entity.getContent();
            }
        }
    }
    catch (IOException e) {
        System.out.println("There was an IO exception\n" + e.toString() );
    }
    return null;
}

And this is the thread's run() method:

@Override
public void run() {
    try {
        requestNegotiate();
        System.out.println("Started Negotiate");
        messageID += 1;
        try (InputStream notificationStream = requestConnect()) {
            messageID += 1;
            System.out.println("Started connect");
            if (notificationStream == null) {
                System.out.println("connect returned null");
            }
            requestStart();
            System.out.println("Started start notification stream");
            if (notificationStream != null) {
                byte[] data = new byte[100];
                notificationStream.read(data);
                System.out.println(data.toString());
            }
            while (notificationStream != null) {
                byte[] inputBuffer = new byte[100];
                notificationStream.read(inputBuffer);
                System.out.println(inputBuffer.toString());

            }
        }
    } catch (IOException e) 
        e.printStackTrace();
    }
}

requestNegotiate(), requestConnect(), and requestStart() call one-line functions that just build the associated URL, then get passed along to grabUrl(). I have verified all the URLs are correct, so I didn't bother to include them in this post.

I've been stuck on this for a couple of days, so any guidance is greatly appreciated. Thanks!

0

There are 0 answers