fix: reset Dio adapters on iOS network switch (#1885)

* fix reset Dio adapters on iOS network switch

* improve iOS connectivity adapter reset safeguards

* refa

---------

Co-authored-by: My-Responsitories <107370289+My-Responsitories@users.noreply.github.com>
This commit is contained in:
0x535A
2026-04-18 12:26:24 +08:00
committed by GitHub
parent db7ad269b2
commit 970ee679f1

View File

@@ -16,6 +16,7 @@ import 'package:PiliPlus/utils/storage_pref.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:archive/archive.dart';
import 'package:brotli/brotli.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:dio/dio.dart';
import 'package:dio/io.dart';
import 'package:dio_http2_adapter/dio_http2_adapter.dart';
@@ -115,28 +116,18 @@ class Request {
return h11;
}
/*
* config it and create
*/
Request._internal() {
//BaseOptions、Options、RequestOptions 都可以配置参数,优先级别依次递增,且可以根据优先级别覆盖参数
BaseOptions options = BaseOptions(
//请求基地址,可以包含子路径
baseUrl: HttpString.apiBaseUrl,
//连接服务器超时时间,单位是毫秒.
connectTimeout: const Duration(milliseconds: 10000),
//响应流上前后两次接受到数据的间隔,单位为毫秒。
receiveTimeout: const Duration(milliseconds: 10000),
//Http请求头.
headers: {
'user-agent': 'Dart/3.6 (dart:io)', // Http2Adapter不会自动添加标头
if (!_enableHttp2) 'connection': 'keep-alive',
'accept-encoding': 'br,gzip',
},
responseDecoder: _responseDecoder, // Http2Adapter没有自动解压
persistentConnection: true,
);
static Timer? _networkChangeDebounce;
static void _watchConnectivity() {
Connectivity().onConnectivityChanged.skip(1).listen((result) {
_networkChangeDebounce?.cancel();
_networkChangeDebounce = Timer(
const Duration(milliseconds: 500),
_resetAdaptersForNetworkChange,
);
});
}
static (IOHttpClientAdapter, ConnectionManager?) _createPool() {
final bool enableSystemProxy;
late final String systemProxyHost;
late final int? systemProxyPort;
@@ -160,30 +151,72 @@ class Request {
..autoUncompress = false, // Http2Adapter没有自动解压, 统一行为
);
final connectionManager = _enableHttp2
? ConnectionManager(
idleTimeout: const Duration(seconds: 15),
onClientCreate: enableSystemProxy
? (_, config) => config
..proxy = Uri(
scheme: 'http',
host: systemProxyHost,
port: systemProxyPort,
)
..onBadCertificate = (_) => true
: Pref.badCertificateCallback
? (_, config) => config.onBadCertificate = (_) => true
: null,
)
: null;
return (http11Adapter, connectionManager);
}
@pragma('vm:notify-debugger-on-exception')
static void _resetAdaptersForNetworkChange() {
try {
final (h11, connectionManager) = _createPool();
if (connectionManager != null) {
(dio.httpClientAdapter as Http2Adapter)
..connectionManager.close(force: true)
..connectionManager = connectionManager
..fallbackAdapter.close(force: true)
..fallbackAdapter = h11;
_http11Dio?.httpClientAdapter = h11;
} else {
dio
..httpClientAdapter.close(force: true)
..httpClientAdapter = h11;
}
} catch (_) {}
}
/*
* config it and create
*/
Request._internal() {
//BaseOptions、Options、RequestOptions 都可以配置参数,优先级别依次递增,且可以根据优先级别覆盖参数
BaseOptions options = BaseOptions(
//请求基地址,可以包含子路径
baseUrl: HttpString.apiBaseUrl,
//连接服务器超时时间,单位是毫秒.
connectTimeout: const Duration(milliseconds: 10000),
//响应流上前后两次接受到数据的间隔,单位为毫秒。
receiveTimeout: const Duration(milliseconds: 10000),
//Http请求头.
headers: {
'user-agent': 'Dart/3.6 (dart:io)', // Http2Adapter不会自动添加标头
if (!_enableHttp2) 'connection': 'keep-alive',
'accept-encoding': 'br,gzip',
},
responseDecoder: _responseDecoder, // Http2Adapter没有自动解压
persistentConnection: true,
);
final (h11, connectionManager) = _createPool();
dio = Dio(options)
..httpClientAdapter = _enableHttp2
? Http2Adapter(
ConnectionManager(
idleTimeout: const Duration(seconds: 15),
onClientCreate: enableSystemProxy
? (_, config) {
config
..proxy = Uri(
scheme: 'http',
host: systemProxyHost,
port: systemProxyPort,
)
..onBadCertificate = (_) => true;
}
: Pref.badCertificateCallback
? (_, config) {
config.onBadCertificate = (_) => true;
}
: null,
),
fallbackAdapter: http11Adapter,
)
: http11Adapter;
? Http2Adapter(connectionManager, fallbackAdapter: h11)
: h11;
// 先于其他Interceptor
if (Pref.retryCount != 0) {
@@ -208,6 +241,8 @@ class Request {
..options.validateStatus = (int? status) {
return status != null && status >= 200 && status < 300;
};
if (Platform.isIOS) _watchConnectivity();
}
/*