此方法提交一个简单的HTTP请求并调用成功或错误回调就好了:
void _getSimpleReply( String command, callback, errorCallback ) async {
try {
HttpClientRequest request = await _myClient.get( _serverIPAddress, _serverPort, '/' );
HttpClientResponse response = await request.close();
response.transform( utf8.decoder ).listen( (onData) { callback( onData ); } );
} on SocketException catch( e ) {
errorCallback( e.toString() );
}
}
Run Code Online (Sandbox Code Playgroud)
如果服务器没有运行,Android-app或多或少会立即调用errorCallback.
在iOS上,errorCallback需要很长一段时间 - 超过20秒 - 直到调用任何回调.
我可以为HttpClient()设置一个等待服务器端返回回复的最大秒数 - 如果有的话?
Cop*_*oad 43
您可以使用 timeout
http.get(Uri.parse('url')).timeout(
Duration(seconds: 1),
onTimeout: () {
// Time has run out, do what you wanted to do.
return http.Response('Error', 500); // Replace 500 with your http code.
},
);
Run Code Online (Sandbox Code Playgroud)
Jon*_*ams 30
在Dart中有两种不同的方法来配置此行为
您可以使用该Future.timeout方法在任何Future上设置超时.这将在给定的持续时间过去之后通过投掷a来短路TimeoutException.
try {
final request = await client.get(...);
final response = await request.close()
.timeout(const Duration(seconds: 2));
// rest of the code
...
} on TimeoutException catch (_) {
// A timeout occurred.
} on SocketException catch (_) {
// Other exception
}
Run Code Online (Sandbox Code Playgroud)
您还可以使用HttpClient本身设置超时HttpClient.connectionTimeout.这将适用于设置超时后由同一客户端发出的所有请求.当请求超过此超时时,SocketException抛出a.
final client = new HttpClient();
client.connectionTimeout = const Duration(seconds: 5);
Run Code Online (Sandbox Code Playgroud)
小智 5
HttpClient.connectionTimeout对我不起作用。不过,我知道Dio数据包允许取消请求。然后,我深入研究数据包,了解他们是如何实现这一目标的,并根据我的情况进行了调整。我所做的是创造两个未来:
Future.delayed设置超时持续时间。然后,我将两个 future 传递给 a Future.any,它返回第一个 future 完成的结果,并丢弃所有其他 future 的结果。因此,如果超时 future 首先完成,您的连接将超时并且不会收到任何响应。您可以通过以下代码查看:
Future<Response> get(
String url, {
Duration timeout = Duration(seconds: 30),
}) async {
final request = Request('GET', Uri.parse(url))..followRedirects = false;
headers.forEach((key, value) {
request.headers[key] = value;
});
final Completer _completer = Completer();
/// Fake timeout by forcing the request future to complete if the duration
/// ends before the response arrives.
Future.delayed(timeout, () => _completer.complete());
final response = await Response.fromStream(await listenCancelForAsyncTask(
_completer,
Future(() {
return _getClient().send(request);
}),
));
}
Future<T> listenCancelForAsyncTask<T>(
Completer completer,
Future<T> future,
) {
/// Returns the first future of the futures list to complete. Therefore,
/// if the first future is the timeout, the http response will not arrive
/// and it is possible to handle the timeout.
return Future.any([
if (completer != null) completeFuture(completer),
future,
]);
}
Future<T> completeFuture<T>(Completer completer) async {
await completer.future;
throw TimeoutException('TimeoutError');
}Run Code Online (Sandbox Code Playgroud)