import 'dart:async'; import 'package:fis_common/http/http.dart'; import 'package:fis_common/http/options.dart'; import 'package:dio/dio.dart' as dio; class _JsonRpcHttpPool { _JsonRpcHttpPool({int limitCount = 2}) { _limitCount = limitCount; } static const _TimerInterval = 60 * 1000; static const _LifecycleTime = 60 * 1000; Timer? _timer; final Map _pool = {}; late int _limitCount; int get limitCount => _limitCount; bool _closed = false; bool _firstCall = true; void _handleFirstLoad() { if (!_firstCall) return; _timer = Timer.periodic(const Duration(milliseconds: _TimerInterval), (timer) { final now = DateTime.now(); _pool.forEach((key, value) { var secDiff = now.difference(value.lastVisitTime).inSeconds; if (_LifecycleTime < secDiff) { _pool.remove(key); } }); }); _firstCall = false; } void close() { if (!_closed) { _closed = true; _timer?.cancel(); } } /// 设置连接池缓存数 void setLimitCount(int count) => _limitCount = count; /// 获取客户端实例 FHttp getClient( String baseUrl, { int? timeout, Map? headers, }) { if (!_pool.containsKey(baseUrl.hashCode)) { // 浏览器跨域限制: Content-Type非简单类型 Fetch前会先发一个Options,Server不支持Options导致Cors // 简单类型: // - application/x-www-form-urlencoded // - multipart/form-data // - text/plain final _client = FHttp(FHttpBaseOptions( baseUrl: baseUrl, timeout: timeout ?? 15 * 1000, headers: headers, contentType: dio.Headers.textPlainContentType, responseType: FHttpResponseType.json, )); final _state = _ClientState(_client); _pool[baseUrl.hashCode] = _state; if (_pool.length > limitCount) { _pool.remove(_pool.keys.first); // 删除第一个 } } final state = _pool[baseUrl.hashCode]!; state.lastVisitTime = DateTime.now(); _handleFirstLoad(); return state.client; } } class _ClientState { _ClientState(this.client); final FHttp client; DateTime lastVisitTime = DateTime.now(); } final _JsonRpcHttpPool jrpcHttpPool = _JsonRpcHttpPool();