如何在Dart中为MultiPart请求设置超时?

时间:2019-10-05 09:42:56

标签: http flutter dart

这是我的MultiPartRequest代码

var request =
            http.MultipartRequest("POST", Uri.parse(EMPLOYEE_PUNCH_IN_URL));

        request.fields['uid'] = userId;
        request.fields['location'] = location;
        request.fields['punchin_time'] = punchInTime;
        request.fields['punchin_location_name'] = address;

        var multiPartFile = await http.MultipartFile.fromPath(
            "photo", imageFile.path,
            contentType: MediaType("image", "$extension"));
        request.files.add(multiPartFile);
        http.StreamedResponse response = await request.send();

        var responseByteArray = await response.stream.toBytes();

        employeePunchInModel = standardSerializers.deserializeWith(
            EmployeePunchInModel.serializer,
            json.decode(utf8.decode(responseByteArray)));
        ......

我知道如何将超时设置为正常的http请求。我已经点击了此链接

Set timeout for HTTPClient get() request

我尝试过通过以下方式添加超时功能,但无法正常工作,我的请求已完成

1。

 var multiPartFile = await http.MultipartFile.fromPath(
            "photo", imageFile.path,
            contentType: MediaType("image", "$extension")).timeout(const Duration(seconds: 1)); 

2。

http.StreamedResponse response = await request.send().timeout(const Duration(seconds: 1));

3。

var responseByteArray = await response.stream.toBytes().timeout(const Duration(seconds: 15));

但以上超时方法均无效。

5 个答案:

答案 0 :(得分:1)

使用带有以下代码的Dio软件包:

  try {
  final response = await Dio().post(requestFinal.item1, data:formData, options: option,
      onSendProgress: (sent, total) {
        print("uploadFile ${sent / total}");
      });

  print("Response Status code:: ${response.statusCode}");

  if (response.statusCode >= 200 && response.statusCode < 299) {

    dynamic jsonResponse = response.data;
    print("response body :: $jsonResponse");
    final message = jsonResponse["msg"] ?? '';
    final status = jsonResponse["status"] ?? 400;
    final data = jsonResponse["data"];
    return HttpResponse(status: status, errMessage: message, json: data);
  }
  else {
    dynamic jsonResponse = response.data;
    print('*********************************************************');
    print("response body :: $jsonResponse");
    print('*********************************************************');
    var errMessage = jsonResponse["msg"];
    return HttpResponse(status: response.statusCode, errMessage: errMessage, json: jsonResponse);
  }
}
on DioError catch(error) {
  print('*********************************************************');
  print('Error Details :: ${error.message}');
  print('*********************************************************');
  dynamic jsonResponse = error.response.data;
  print('*********************************************************');
  print("response body :: $jsonResponse");
  print('*********************************************************');
  var errMessage = jsonResponse["message"] ?? "Something went wrong";
  return HttpResponse(status: jsonResponse["status"] , errMessage:  errMessage, json: null);
}                                                                                      

希望这会有所帮助!

答案 1 :(得分:0)

我建议

var request = http.MultipartRequest("POST", Uri.parse(EMPLOYEE_PUNCH_IN_URL));

  request.fields['uid'] = userId;
  request.fields['location'] = location;
  request.fields['punchin_time'] = punchInTime;
  request.fields['punchin_location_name'] = address;

  var multiPartFile = await http.MultipartFile.fromPath(
      "photo", imageFile.path,
      contentType: MediaType("image", "$extension"));
  request.files.add(multiPartFile);

  await request.send().timeout(Duration(seconds: 1), onTimeout: () {
    throw "TimeOut";
  }).then((onValue) {
    var responseByteArray = await onValue.stream.toBytes();

    employeePunchInModel = standardSerializers.deserializeWith(
        EmployeePunchInModel.serializer,
        json.decode(utf8.decode(responseByteArray)));
  }).catchError((){ throw "TimeOut";});

答案 2 :(得分:0)

嘿,您也可以使用 dio 3.0.4

Dart的功能强大的Http客户端,它支持拦截器,全局配置,FormData,请求取消,文件下载,超时等。

这是链接:Http client for Dart

答案 3 :(得分:0)

你可以试试这个使用 http package

用你想要的参数像这样声明你的多部分函数

 Future<http.Response> makeAnyHttpRequest(String url,
      Map<String, dynamic> body,
      {Function onTimeout,
      Duration duration = const Duration(seconds: 10)}) async {
    final request = http.MultipartRequest(
      'POST',
      Uri.parse('$url'),
    );
    final res = await request.send().timeout(duration, onTimeout: onTimeout);
    return await http.Response.fromStream(res);
  }

然后在 try catch 块中调用它,您可以通过在 Timeout 上抛出所需的值来捕获超时异常。

try{
    final res = makeAnyHttpRequest("<url>",{"body":"here"},onTimeout:(){
      throw 'TIME_OUT'; // Throw anything
    });
      
  }catch(_){
      if (_.toString() == 'TIME_OUT') { // catch the thrown value to detect TIMEOUT
        /// DO SOMETHING ON TIMEOUT    
          debugPrint('The request Timeout');   
     }
  }
}

上述方法适用于任何 http 请求,只要您有 onTimeout 回调

答案 4 :(得分:0)

使用 http package,这是我的方法:

  1. 创建一个我们将用于 onTimeOut 回调的流式响应
StreamedResponse timeOutResponse({
  @required String httpMethod,
  @required dynamic error,
  @required String url,
}) { 
  Map<String, dynamic> body = {
    'any': 'value',   
    'you': 'want for $error',
  };

  int statusCode = 404;  
  Uri destination = Uri.parse(url);
  String json = jsonEncode(body);
  
  return StreamedResponse(
    Stream.value(json.codeUnits),
    statusCode,
    request: Request(httpMethod, destination),
  );
}
  1. 使用 Mahesh Jamdade 答案中修改后的 http 多部分函数
Future<http.Response> makeAnyHttpRequest(String url,
  Map<String, dynamic> body,
  {Function onTimeout,
  Duration duration = const Duration(seconds: 10)}) async {

     final request = http.MultipartRequest(
         'POST',
          Uri.parse('$url'),
       );
     
     final res = await request.send().timeout(
         duration,
         onTimeout: () {
           return timeOutResponse(
             httpMethod: 'MULTIPART POST',
             error: 'Request Time Out',
             url: url,
           );
         },
       );

     return await http.Response.fromStream(res);
  }

这样,您可以返回 onTimeOut Http Response 而不是超时异常。