简体   繁体   English

如何在Flutter中取消通过http.MultipartRequest()发送的正在进行的文件上传?

[英]How to cancel ongoing file upload sent with http.MultipartRequest() in Flutter?

I'm trying to add cancel functionality to file upload in my Flutter app. 我正在尝试在Flutter应用程序中为文件上传添加取消功能。 I'm currently using http.MultipartRequest() from http package to upload the file. 我目前正在使用http package http.MultipartRequest()上传文件。 I've tried wrapping the upload with CancelableOperation but it only cancels the internal process within my Flutter app and the file still gets uploaded successfully to my Firebase Storage server. 我尝试用CancelableOperation包装上传文件,但它只会取消Flutter应用程序中的内部进程,并且文件仍成功上传到Firebase Storage服务器。

I read the README.md on http package about using http.Client() and closing it after the http request is completed. 我阅读了有关使用http.Client()并在http请求完成后将其关闭的http包上的http.Client() I'm thinking about using http.Client() to upload the file and then closing it with the http.Client().close() to cancel the http request. 我正在考虑使用http.Client()上传文件,然后使用http.Client().close()关闭该文件以取消http请求。

But, I haven't found the right way to upload file with http.Client yet. 但是,我还没有找到使用http.Client上传文件的正确方法。 I browsed about it on Google and stackoverflow but all the posts recommend using http.MultipartRequest() . 我在Google和stackoverflow上进行了浏览,但是所有帖子都建议使用http.MultipartRequest() One of the posts 帖子之一

So, my questions are: 1. Is it possible to cancel upload file sent with http.MultipartRequest() from http package in Flutter? 因此,我的问题是:1.是否可以从Flutter中的http包中取消使用http.MultipartRequest()发送的上传文件? 2. Am I in the right track with trying to use http.Client() ? 2.我是否在尝试使用http.Client()的正确轨道上? Or is there any better way to do this? 还是有更好的方法来做到这一点? 3. If using http.Client() is the only way, then can you please show me how to upload file with http.Client() ? 3.如果唯一的方法是使用http.Client() ,那么您能告诉我如何使用http.Client()上传文件吗? since it only has post() and no multipartrequest() . 因为它只有post()而没有multipartrequest()

Sorry for the long text. 抱歉,长文本。 Please help. 请帮忙。 Thanks! 谢谢!

Package http uses HTTPClient under the hood. httpHTTPClient使用HTTPClient It wraps that underlying client in an IOClient . 它将底层客户端包装在IOClient Most of http 's methods (like get and post ) allow you to pass in your own client, but the MultipartRequest doesn't (it creates one for each request). http的大多数方法(如getpost )都允许您传入自己的客户端,但是MultipartRequest不允许(它为每个请求创建一个)。

The easiest solution seems to be to subclass it. 最简单的解决方案似乎是对其进行子类化。

import 'dart:async';
import 'dart:io';

import 'package:http/http.dart' as http;

class CloseableMultipartRequest extends http.MultipartRequest {
  http.IOClient client = http.IOClient(HttpClient());

  CloseableMultipartRequest(String method, Uri uri) : super(method, uri);

  void close() => client.close();

  @override
  Future<http.StreamedResponse> send() async {
    try {
      var response = await client.send(this);
      var stream = onDone(response.stream, client.close);
      return new http.StreamedResponse(
        new http.ByteStream(stream),
        response.statusCode,
        contentLength: response.contentLength,
        request: response.request,
        headers: response.headers,
        isRedirect: response.isRedirect,
        persistentConnection: response.persistentConnection,
        reasonPhrase: response.reasonPhrase,
      );
    } catch (_) {
      client.close();
      rethrow;
    }
  }

  Stream<T> onDone<T>(Stream<T> stream, void onDone()) =>
      stream.transform(new StreamTransformer.fromHandlers(handleDone: (sink) {
        sink.close();
        onDone();
      }));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM