Sdk: Get Progress Event on Multipart Request

Created on 17 Dec 2018  路  11Comments  路  Source: dart-lang/sdk

Of course, I should have filed this request on http package repository, but I found this there dart-lang/http#153. Then asked a question on SO, added a bounty on it too, asked on gitter, but sadly I got no reply. Filed an issue https://github.com/flutter/flutter/issues/25444 on flutter SDK and I was directed here.

Is there any workaround for this behavior? If no, this might actually be a feature request.

SO Question: https://stackoverflow.com/questions/53727911/how-to-get-progress-event-while-uploading-file-on-http-multipartrequest-request.

Thanks in advance!!!

P2 area-library library-io type-enhancement

Most helpful comment

The DIO solution does not solve the issue. With a slow connection, my upload is taking 15~20 secs to complete, but I can't show the upload percentage correctly, because it suddenly goes from 0% to 100%.

I/flutter ( 4238): 0 of 0 (0%)
I/flutter ( 4238): 29 of 4943262 (0%)
I/flutter ( 4238): 78 of 4943262 (0%)
I/flutter ( 4238): 102 of 4943262 (0%)
I/flutter ( 4238): 104 of 4943262 (0%)
I/flutter ( 4238): 133 of 4943262 (0%)
I/flutter ( 4238): 277 of 4943262 (0%)
I/flutter ( 4238): 4943229 of 4943262 (100%)
I/flutter ( 4238): 4943231 of 4943262 (100%)
I/flutter ( 4238): 4943262 of 4943262 (100%)

All 11 comments

After waiting for a week or soo for an answer, I created a plugin to get this behavior. Package https://pub.dartlang.org/packages/multipart_request .

Example to use it:

var request = MultipartRequest();

request.addFile("image", imagePath);

Response response = request.send();

response.onError = () {
  print("Error");
};

response.onComplete = (response) {
  print(response);
};

response.progress.listen((int progress) {
  print("progress from response object " + progress.toString());
});

Works only on android.
Hope it helps someone who's wondering around for the same question.

For raw non-mulipart upload requests you can forward file stream to request's stream.
By adding map function to it you can calculate progress.

Example: https://gist.github.com/dru/85975bf55151e7f160a10cdd3575e9be
Minimal upload server on Rust: https://gist.github.com/dru/7e29eec44230aa6d455d1c52881116eb

Any news?

No news right now. I'm currently triaging the dart:io issues, understanding what's important to people (bunch of interest in this issue for instance), and planning what to work on.

No news right now. I'm currently triaging the dart:io issues, understanding what's important to people (bunch of interest in this issue for instance), and planning what to work on.

What do you think about the implementation of the unloading link below, there is a calculation of how many bytes were read from the file, but not sent to the network. The code works quite well, tell me what the minus of this solution is, the pitfalls
project

Any news on this request ?
I would be very usefull to me :)

What do you think about the implementation of the unloading link below, there is a calculation of how many bytes were read from the file, but not sent to the network. The code works quite well, tell me what the minus of this solution is, the pitfalls
project

This is not actually a solution though. Because reading the bytes of a file is done quite quickly, meaning the progress bar will skip from 0% - 100% within a ~second. After that it just stays on 100% for a while (depending on the file size) while it's actually uploading the file.

I really need that upload progress to be available so that I can smoothly report the upload progress to the user. I've listed the solutions that I've tried in this SO question (including your suggestion). They all come back to the HTTP package not supporting the upload progress natively.

Do we have any info yet if and when this will be added?

Dio package now supports progress callback if I recall correctly. Try migrating to dio if thats possible. Ref: https://github.com/flutterchina/dio/issues/103

@awazgyawali Thank you for the reply! As you can see in my SO question, I've tried the DIO solution already, together with my custom solution (which basically do the same thing).

They both read the file into a stream and report the progress of that, not the uploading progress it self. So basically I think the following is happening when you upload using DIO or my solution:

1) You select a file and start the upload.
2) The selected file is read into a stream.
3) While reading that file into a stream, the bytes read is reported as progress. This is done quite quickly, which makes the progress bar skip from 0% to 100% in within a ~second and in few steps. See below for my print out from a ~10 MB file, which is basically printed within one second.

flutter: progress: 0.000003035281907563734 (29/9554302)
flutter: progress: 0.000013187776563897604 (126/9554302)
flutter: progress: 0.999996546058519 (9554269/9554302)
flutter: progress: 0.9999967553883057 (9554271/9554302)
flutter: progress: 1.0 (9554302/9554302)

4) The request starts uploading the stream and you have to wait a certain amount of time for that to finish. In the meantime, the progress bar is already on 100%, so you're basically watching that 100% filled progress bar for a few seconds (depending on the file size).
5) After waiting a while, the 2xx response from the server is received and your upload is finished.

So no, I don't think my custom solution and that of DIO is the proper upload progress.

From my own research into this, it appears you'll never get a very accurate progress monitoring because AFAIK no operating system reports the bytes leaving the network interface for each individual stream.

The way I've seen this solved in other languages and frameworks has always been to count the bytes going into the upper layers of the network model. This isn't perfect since there are buffers involved, causing the first few kb/mb to be "sent" immediately, as well the process to "hang" on 100% for a second or two before completing. But it does a good enough job for most applications.

The DIO solution does not solve the issue. With a slow connection, my upload is taking 15~20 secs to complete, but I can't show the upload percentage correctly, because it suddenly goes from 0% to 100%.

I/flutter ( 4238): 0 of 0 (0%)
I/flutter ( 4238): 29 of 4943262 (0%)
I/flutter ( 4238): 78 of 4943262 (0%)
I/flutter ( 4238): 102 of 4943262 (0%)
I/flutter ( 4238): 104 of 4943262 (0%)
I/flutter ( 4238): 133 of 4943262 (0%)
I/flutter ( 4238): 277 of 4943262 (0%)
I/flutter ( 4238): 4943229 of 4943262 (100%)
I/flutter ( 4238): 4943231 of 4943262 (100%)
I/flutter ( 4238): 4943262 of 4943262 (100%)
Was this page helpful?
0 / 5 - 0 ratings

Related issues

bergwerf picture bergwerf  路  3Comments

55555Mohit55555 picture 55555Mohit55555  路  3Comments

Hixie picture Hixie  路  3Comments

DartBot picture DartBot  路  3Comments

xster picture xster  路  3Comments