0

I am trying to implement async file upload with progress with sonatype async http client - https://github.com/sonatype/async-http-client.

I tried the method suggested in the docs. Using transfer listener. http://sonatype.github.com/async-http-client/transfer-listener.html

I implemented onBytesSent of TransferListener interface (just as test):

public void onBytesSent(ByteBuffer byteBuffer) {

     System.out.println("Total bytes sent - ");
     System.out.println(byteBuffer.capacity());
}

Then in another thread(because I don't want to block the app) I tried to do the following:

TransferCompletionHandler tl = new TransferCompletionHandler();
tl.addTransferListener(listener);

asyncHttpClient.preparePut(getFullUrl(fileWithPath))
      .setBody(new BodyGenerator() {
           public Body createBody() throws IOException {
                return new FileBodyWithOffset(file, offset);
           }
       })
       .addHeader(CONTENT_RANGE, new ContentRange(offset, localSize).toString())
       .execute(handler).get();

Everything is fine. File is uploaded correctly and very fast. But the issue is - I am getting messages from onBytesSent in TransferListener only AFTER the upload is finished. For exmaple the upload is completed in 10 minutes. And during that 10 minutes I get nothing. And only after that everything is printed on the console.

I can't figure out what is wrong with this code. I just tried to follow the docs.

I tried to execute the above code in the main thread and it didn't work either.

Maybe it is a wrong way to implement upload progress listener using this client?

JohnGray
  • 656
  • 1
  • 10
  • 27

1 Answers1

2

I will answer it myself. I did not manage to resolve the issue with TransferListener. So I tried the other way.

I had put the progress logick inside Body interface implementation (inside read method):

public class FileBodyWithOffset implements Body {

    private final ReadableByteChannel channel;

    private long actualOffset;

    private final long contentLength;

    public FileBodyWithOffset(final File file, final long offset) throws IOException {

        final InputStream stream = new FileInputStream(file);

        this.actualOffset = stream.skip(offset);

        this.contentLength = file.length() - offset;

        this.channel = Channels.newChannel(stream);
    }


    public long getContentLength() {

        return this.contentLength;
    }

    public long read(ByteBuffer byteBuffer) throws IOException {

        System.out.println(new Date());

        actualOffset += byteBuffer.capacity();

        return channel.read(byteBuffer);
    }

    public void close() throws IOException {

        channel.close();
    }

    public long getActualOffset() {

        return actualOffset;
    }
}

Maybe it is a dirty trick, but at least it works.

JohnGray
  • 656
  • 1
  • 10
  • 27