diff --git a/packages/stream_chat/lib/src/core/http/interceptor/auth_interceptor.dart b/packages/stream_chat/lib/src/core/http/interceptor/auth_interceptor.dart index 19d0293b..a75b2d2c 100644 --- a/packages/stream_chat/lib/src/core/http/interceptor/auth_interceptor.dart +++ b/packages/stream_chat/lib/src/core/http/interceptor/auth_interceptor.dart @@ -1,6 +1,7 @@ import 'package:dio/dio.dart'; import 'package:stream_chat/src/core/api/responses.dart'; import 'package:stream_chat/src/core/http/stream_chat_dio_error.dart'; +import 'package:stream_chat/src/core/http/stream_http_client.dart'; import 'package:stream_chat/src/core/http/token.dart'; import 'package:stream_chat/src/core/http/token_manager.dart'; @@ -10,9 +11,9 @@ import 'package:stream_chat/src/errors/stream_chat_error.dart'; /// class AuthInterceptor extends Interceptor { /// - AuthInterceptor(this._httpClient, this._tokenManager); + AuthInterceptor(this._client, this._tokenManager); - final Dio _httpClient; + final StreamHttpClient _client; /// final TokenManager _tokenManager; @@ -52,12 +53,12 @@ class AuthInterceptor extends Interceptor { if (data != null) error = ErrorResponse.fromJson(data); if (error?.code == ChatErrorCode.tokenExpired.code) { if (_tokenManager.isStatic) return handler.next(err); - _httpClient.lock(); + _client.lock(); await _tokenManager.loadToken(refresh: true); - _httpClient.unlock(); + _client.unlock(); try { final options = err.requestOptions; - final response = await _httpClient.request( + final response = await _client.request( options.path, cancelToken: options.cancelToken, data: options.data, diff --git a/packages/stream_chat/lib/src/core/http/stream_http_client.dart b/packages/stream_chat/lib/src/core/http/stream_http_client.dart index 43149714..e5c1e82b 100644 --- a/packages/stream_chat/lib/src/core/http/stream_http_client.dart +++ b/packages/stream_chat/lib/src/core/http/stream_http_client.dart @@ -40,7 +40,7 @@ class StreamHttpClient { 'Content-Encoding': 'application/gzip', } ..interceptors.addAll([ - if (tokenManager != null) AuthInterceptor(httpClient, tokenManager), + if (tokenManager != null) AuthInterceptor(this, tokenManager), if (connectionIdManager != null) ConnectionIdInterceptor(connectionIdManager), if (logger != null && logger.level != Level.OFF) @@ -74,9 +74,23 @@ class StreamHttpClient { @visibleForTesting final Dio httpClient; - /// Shuts down the [httpClient]. + /// Lock the current [StreamHttpClient] instance. /// - /// If [force] is `false` (the default) the [httpClient] will be kept alive + /// [StreamHttpClient] will enqueue the incoming request tasks instead + /// send them directly when [interceptor.requestOptions] is locked. + void lock() => httpClient.lock(); + + /// Unlock the current [StreamHttpClient] instance. + /// + /// [StreamHttpClient] instance dequeue the request task。 + void unlock() => httpClient.unlock(); + + ///Clear the current [StreamHttpClient] instance waiting queue. + void clear() => httpClient.close(); + + /// Shuts down the [StreamHttpClient]. + /// + /// If [force] is `false` the [StreamHttpClient] will be kept alive /// until all active connections are done. If [force] is `true` any active /// connections will be closed to immediately release all resources. These /// closed connections will receive an error event to indicate that the client @@ -237,4 +251,30 @@ class StreamHttpClient { ); return response; } + + /// Handy method to make generic http request with error parsing. + Future> request( + String path, { + Object? data, + Map? queryParameters, + Options? options, + ProgressCallback? onSendProgress, + ProgressCallback? onReceiveProgress, + CancelToken? cancelToken, + }) async { + try { + final response = await httpClient.request( + path, + data: data, + queryParameters: queryParameters, + options: options, + onSendProgress: onSendProgress, + onReceiveProgress: onReceiveProgress, + cancelToken: cancelToken, + ); + return response; + } on DioError catch (error) { + throw _parseError(error); + } + } }