mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 15:57:25 +00:00
improve network request
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
@@ -176,6 +177,8 @@ class AppDio with DioMixin {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static final Map<String, bool> _requests = {};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Response<T>> request<T>(
|
Future<Response<T>> request<T>(
|
||||||
String path, {
|
String path, {
|
||||||
@@ -186,6 +189,13 @@ class AppDio with DioMixin {
|
|||||||
ProgressCallback? onSendProgress,
|
ProgressCallback? onSendProgress,
|
||||||
ProgressCallback? onReceiveProgress,
|
ProgressCallback? onReceiveProgress,
|
||||||
}) async {
|
}) async {
|
||||||
|
if(options?.headers?['prevent-parallel'] == 'true') {
|
||||||
|
while(_requests.containsKey(path)) {
|
||||||
|
await Future.delayed(const Duration(milliseconds: 20));
|
||||||
|
}
|
||||||
|
_requests[path] = true;
|
||||||
|
options!.headers!.remove('prevent-parallel');
|
||||||
|
}
|
||||||
proxy = await getProxy();
|
proxy = await getProxy();
|
||||||
if (_proxy != proxy) {
|
if (_proxy != proxy) {
|
||||||
Log.info("Network", "Proxy changed to $proxy");
|
Log.info("Network", "Proxy changed to $proxy");
|
||||||
@@ -196,7 +206,7 @@ class AppDio with DioMixin {
|
|||||||
: rhttp.ProxySettings.proxy(proxy!),
|
: rhttp.ProxySettings.proxy(proxy!),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
return super.request(
|
var res = super.request<T>(
|
||||||
path,
|
path,
|
||||||
data: data,
|
data: data,
|
||||||
queryParameters: queryParameters,
|
queryParameters: queryParameters,
|
||||||
@@ -205,6 +215,10 @@ class AppDio with DioMixin {
|
|||||||
onSendProgress: onSendProgress,
|
onSendProgress: onSendProgress,
|
||||||
onReceiveProgress: onReceiveProgress,
|
onReceiveProgress: onReceiveProgress,
|
||||||
);
|
);
|
||||||
|
if(_requests.containsKey(path)) {
|
||||||
|
_requests.remove(path);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
import 'dart:async';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
|
|
||||||
class NetworkCache {
|
class NetworkCache {
|
||||||
@@ -64,17 +63,11 @@ class NetworkCacheManager implements Interceptor {
|
|||||||
size = 0;
|
size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var preventParallel = <Uri, Completer>{};
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onError(DioException err, ErrorInterceptorHandler handler) {
|
void onError(DioException err, ErrorInterceptorHandler handler) {
|
||||||
if (err.requestOptions.method != "GET") {
|
if (err.requestOptions.method != "GET") {
|
||||||
return handler.next(err);
|
return handler.next(err);
|
||||||
}
|
}
|
||||||
if(preventParallel[err.requestOptions.uri] != null){
|
|
||||||
preventParallel[err.requestOptions.uri]!.complete();
|
|
||||||
preventParallel.remove(err.requestOptions.uri);
|
|
||||||
}
|
|
||||||
return handler.next(err);
|
return handler.next(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,18 +77,12 @@ class NetworkCacheManager implements Interceptor {
|
|||||||
if (options.method != "GET") {
|
if (options.method != "GET") {
|
||||||
return handler.next(options);
|
return handler.next(options);
|
||||||
}
|
}
|
||||||
if(preventParallel[options.uri] != null){
|
|
||||||
await preventParallel[options.uri]!.future;
|
|
||||||
}
|
|
||||||
var cache = getCache(options.uri);
|
var cache = getCache(options.uri);
|
||||||
if (cache == null || !compareHeaders(options.headers, cache.requestHeaders)) {
|
if (cache == null ||
|
||||||
|
!compareHeaders(options.headers, cache.requestHeaders)) {
|
||||||
if (options.headers['cache-time'] != null) {
|
if (options.headers['cache-time'] != null) {
|
||||||
options.headers.remove('cache-time');
|
options.headers.remove('cache-time');
|
||||||
}
|
}
|
||||||
if(options.headers['prevent-parallel'] != null){
|
|
||||||
options.headers.remove('prevent-parallel');
|
|
||||||
preventParallel[options.uri] = Completer();
|
|
||||||
}
|
|
||||||
return handler.next(options);
|
return handler.next(options);
|
||||||
} else {
|
} else {
|
||||||
if (options.headers['cache-time'] == 'no') {
|
if (options.headers['cache-time'] == 'no') {
|
||||||
@@ -106,20 +93,21 @@ class NetworkCacheManager implements Interceptor {
|
|||||||
}
|
}
|
||||||
var time = DateTime.now();
|
var time = DateTime.now();
|
||||||
var diff = time.difference(cache.time);
|
var diff = time.difference(cache.time);
|
||||||
if (options.headers['cache-time'] == 'long'
|
if (options.headers['cache-time'] == 'long' &&
|
||||||
&& diff < const Duration(hours: 2)) {
|
diff < const Duration(hours: 2)) {
|
||||||
return handler.resolve(Response(
|
return handler.resolve(Response(
|
||||||
requestOptions: options,
|
requestOptions: options,
|
||||||
data: cache.data,
|
data: cache.data,
|
||||||
headers: Headers.fromMap(cache.responseHeaders),
|
headers: Headers.fromMap(cache.responseHeaders)
|
||||||
|
..set('venera-cache', 'true'),
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
));
|
));
|
||||||
}
|
} else if (diff < const Duration(seconds: 5)) {
|
||||||
else if (diff < const Duration(seconds: 5)) {
|
|
||||||
return handler.resolve(Response(
|
return handler.resolve(Response(
|
||||||
requestOptions: options,
|
requestOptions: options,
|
||||||
data: cache.data,
|
data: cache.data,
|
||||||
headers: Headers.fromMap(cache.responseHeaders),
|
headers: Headers.fromMap(cache.responseHeaders)
|
||||||
|
..set('venera-cache', 'true'),
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
));
|
));
|
||||||
} else if (diff < const Duration(hours: 1)) {
|
} else if (diff < const Duration(hours: 1)) {
|
||||||
@@ -133,7 +121,8 @@ class NetworkCacheManager implements Interceptor {
|
|||||||
return handler.resolve(Response(
|
return handler.resolve(Response(
|
||||||
requestOptions: options,
|
requestOptions: options,
|
||||||
data: cache.data,
|
data: cache.data,
|
||||||
headers: Headers.fromMap(cache.responseHeaders),
|
headers: Headers.fromMap(cache.responseHeaders)
|
||||||
|
..set('venera-cache', 'true'),
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -143,6 +132,10 @@ class NetworkCacheManager implements Interceptor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool compareHeaders(Map<String, dynamic> a, Map<String, dynamic> b) {
|
static bool compareHeaders(Map<String, dynamic> a, Map<String, dynamic> b) {
|
||||||
|
a.remove('cache-time');
|
||||||
|
a.remove('prevent-parallel');
|
||||||
|
b.remove('cache-time');
|
||||||
|
b.remove('prevent-parallel');
|
||||||
if (a.length != b.length) {
|
if (a.length != b.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -175,10 +168,6 @@ class NetworkCacheManager implements Interceptor {
|
|||||||
);
|
);
|
||||||
setCache(cache);
|
setCache(cache);
|
||||||
}
|
}
|
||||||
if(preventParallel[response.requestOptions.uri] != null){
|
|
||||||
preventParallel[response.requestOptions.uri]!.complete();
|
|
||||||
preventParallel.remove(response.requestOptions.uri);
|
|
||||||
}
|
|
||||||
handler.next(response);
|
handler.next(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,6 +178,9 @@ class NetworkCacheManager implements Interceptor {
|
|||||||
if (data is List<int>) {
|
if (data is List<int>) {
|
||||||
return data.length;
|
return data.length;
|
||||||
}
|
}
|
||||||
|
if (data is Uint8List) {
|
||||||
|
return data.length;
|
||||||
|
}
|
||||||
if (data is String) {
|
if (data is String) {
|
||||||
if (data.trim().isEmpty) {
|
if (data.trim().isEmpty) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -58,8 +58,9 @@ class ImageDownloader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configs['onResponse'] != null) {
|
if (configs['onResponse'] is JSInvokable) {
|
||||||
buffer = configs['onResponse'](buffer);
|
buffer = (configs['onResponse'] as JSInvokable)([buffer]);
|
||||||
|
(configs['onResponse'] as JSInvokable).free();
|
||||||
}
|
}
|
||||||
|
|
||||||
await CacheManager().writeCache(cacheKey, buffer);
|
await CacheManager().writeCache(cacheKey, buffer);
|
||||||
@@ -102,7 +103,7 @@ class ImageDownloader {
|
|||||||
|
|
||||||
if (configs['onLoadFailed'] is JSInvokable) {
|
if (configs['onLoadFailed'] is JSInvokable) {
|
||||||
onLoadFailed = () async {
|
onLoadFailed = () async {
|
||||||
dynamic result = configs['onLoadFailed']();
|
dynamic result = (configs['onLoadFailed'] as JSInvokable)([]);
|
||||||
if (result is Future) {
|
if (result is Future) {
|
||||||
result = await result;
|
result = await result;
|
||||||
}
|
}
|
||||||
@@ -135,8 +136,9 @@ class ImageDownloader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configs['onResponse'] != null) {
|
if (configs['onResponse'] is JSInvokable) {
|
||||||
buffer = configs['onResponse'](buffer);
|
buffer = (configs['onResponse'] as JSInvokable)([buffer]);
|
||||||
|
(configs['onResponse'] as JSInvokable).free();
|
||||||
}
|
}
|
||||||
|
|
||||||
var data = Uint8List.fromList(buffer);
|
var data = Uint8List.fromList(buffer);
|
||||||
@@ -162,6 +164,7 @@ class ImageDownloader {
|
|||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
var newConfig = await onLoadFailed();
|
var newConfig = await onLoadFailed();
|
||||||
|
(configs['onLoadFailed'] as JSInvokable).free();
|
||||||
onLoadFailed = null;
|
onLoadFailed = null;
|
||||||
if (newConfig == null) {
|
if (newConfig == null) {
|
||||||
rethrow;
|
rethrow;
|
||||||
@@ -169,6 +172,11 @@ class ImageDownloader {
|
|||||||
configs = newConfig;
|
configs = newConfig;
|
||||||
retryLimit--;
|
retryLimit--;
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
if(onLoadFailed != null) {
|
||||||
|
(configs['onLoadFailed'] as JSInvokable).free();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user