我们处于生产应用程序面临以下套接字异常并且在此之后无法执行任何其他网络操作的情况。
DioError [DioErrorType.DEFAULT]: SocketException: Failed host lookup: ‘xyz.abc.com’ (OS Error: nodename nor servname provided, or not known, errno = 8)
注意:反复遇到一位使用 iPhone X、iOS 14.4 的用户
我们使用Dio作为网络客户端,使用Retrofit,它在内部使用来自 dart 的 HttpClient。使用 Dio 的异常不能在模拟环境中重现,但直接使用 HttpClient,可以在 iOS 模拟器中使用以下代码重现相同的异常。
HttpClient userAgent = new HttpClient();
bool run = true;
while (run) {
try {
await userAgent.getUrl(Uri.parse('https://www.google.com'));
print('Number of api executed');
} catch (e) {
print(e);
if (e is SocketException) {
if ((e as SocketException).osError.errorCode == 8)
print('***** Exception Caught *****');
}
}
}
一旦抛出异常,HttpClient 就无法从该陈旧状态中恢复,并且所有其他 API 请求都开始失败并出现相同的错误。
我们能够通过强制关闭所有先前的连接并打开一个新的 HttpClient 来从该陈旧状态中恢复。
HttpClient userAgent = new HttpClient();
bool run = true;
while (run) {
try {
await userAgent.getUrl(Uri.parse('https://www.google.com'));
print('Number of api executed');
} catch (e) {
print(e);
if (e is SocketException) {
if ((e as SocketException).osError.errorCode == 8)
print('***** Exception Caught *****');
}
userAgent.close(force: true);
print('Force closing previous connections');
userAgent = HttpClient();
print('Creating new HttpClient instance');
}
}
一个有趣的事实是在每 236 个请求之后引发异常。这可能是因为文件描述符过度使用,但 iOS 有 256 个限制。
有了稳定的互联网连接,这个问题每次都可以在 iOS 模拟器中重现。
虽然我无法重现 Dio 客户端的问题,但在生产中它正在发生。因此,我正在寻求帮助以了解此问题的根本原因,以及我们如何预防它?
任何遇到过这种情况以及如何克服它的人,请帮助我。
提前致谢。