在 flutter 中收到完整标头之前连接已关闭 http post

Dey*_*Paz 2 android-studio flutter dio

我在尝试使用我的 API 时遇到问题,在跟进这个问题后,我陷入了困境,我尝试了不同版本的不同模拟器,但问题仍然存在。

错误:

DioError [DioErrorType.other]: HttpException: Connection closed before full header was received, uri = http://10.0.2.2:7108/Users/authenticate
Run Code Online (Sandbox Code Playgroud)

扑医生

在此输入图像描述

HTTP 邮递

class AuthenticateRemoteApi extends AuthenticateGateway {
  final AuthenticateMapper _authenticateMapper = AuthenticateMapper();

  @override
  Future<SesionUser> login(Authenticate user) async {
    var dio = Dio();
    dio.options.headers['content-Type'] = 'application/json';
    String url = 'http://10.0.2.2:7108/Users/authenticate';

    try {
      Response response = await dio.post(url, data: authenticateModelToJson(user));
      return _authenticateMapper.fromMap(jsonDecode(response.data));
    } catch (e) {
      throw Exception(e);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

小智 6

我通过创建这个拦截器来解决这个问题。

它的想法是当遇到这个随机错误时只是重试请求。

/// Interceptor
class RetryOnConnectionChangeInterceptor extends Interceptor {
  final Dio dio;

  RetryOnConnectionChangeInterceptor({
    required this.dio,
  });

  @override
  void onError(DioError err, ErrorInterceptorHandler handler) async {
  if (_shouldRetryOnHttpException(err)) {
      try {
        handler.resolve(await DioHttpRequestRetrier(dio: dio).requestRetry(err.requestOptions).catchError((e) {
          handler.next(err);
        }));
      } catch (e) {
        handler.next(err);
      }
    } else {
      handler.next(err);
    }

  }

  bool _shouldRetryOnHttpException(DioError err) {
    return err.type == DioErrorType.other &&
        ((err.error is HttpException && err.message.contains('Connection closed before full header was received')));
  }
}

/// Retrier
class DioHttpRequestRetrier {
  final Dio dio;

  DioHttpRequestRetrier({
    required this.dio,
  });

  Future<Response> requestRetry(RequestOptions requestOptions) async {
    return dio.request(
      requestOptions.path,
      cancelToken: requestOptions.cancelToken,
      data: requestOptions.data,
      onReceiveProgress: requestOptions.onReceiveProgress,
      onSendProgress: requestOptions.onSendProgress,
      queryParameters: requestOptions.queryParameters,
      options: Options(
        contentType: requestOptions.contentType,
        headers: requestOptions.headers,
        sendTimeout: requestOptions.sendTimeout,
        receiveTimeout: requestOptions.receiveTimeout,
        extra: requestOptions.extra,
        followRedirects: requestOptions.followRedirects,
        listFormat: requestOptions.listFormat,
        maxRedirects: requestOptions.maxRedirects,
        method: requestOptions.method,
        receiveDataWhenStatusError: requestOptions.receiveDataWhenStatusError,
        requestEncoder: requestOptions.requestEncoder,
        responseDecoder: requestOptions.responseDecoder,
        responseType: requestOptions.responseType,
        validateStatus: requestOptions.validateStatus,
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

用法:将此拦截器 [RetryOnConnectionChangeInterceptor] 添加到您的 Dio 客户端实例