当我使用URLSession进行POST API调用时,在API执行过程中发生网络断开,我收到来自URLSession的网络错误回调-

Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={_kCFStreamErrorCodeKey=53, NSUnderlyingError=0x2822cc9f0 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={_kCFStreamErrorCodeKey=53, _kCFStreamErrorDomainKey=1}}

然后,如果网络立即重新连接,URLSession将静默重试API调用,并且我不会收到对所做API调用的任何确认.

当我们收到网络错误时,我们认为调用失败,并try 重试API.至此,进行了2次API调用,one from my retry mechanism and another from URL session auto retry mechanism.

有什么方法可以告诉URL会话不要自动重试吗?对于我来说,重要的是避免对后端进行重复的API调用.

这是我的URLSession配置-

let config = URLSessionConfiguration.default
config.waitsForConnectivity = true
config.timeoutIntervalForRequest = 1
config.timeoutIntervalForResource = 1
URLSession.shared.dataTask(with: request.urlRequest!) {data, response, error in
    // Do something
}.resume()

推荐答案

要确认从一个数据任务实际建立了两个连接,您需要判断服务器日志(log);您将实际看到三个连接:

  • 原始连接
  • "已重试"连接
  • 代码在收到错误后建立的第二个连接.

然而,我高度怀疑这是正在发生的事情.您将看到两个连接;您的原始连接和您的代码在错误后建立的第二个连接.

更有可能的情况是,您的服务器已提交事务,而网络在返回结果之前已出现故障.

网络连接故障基本上可能发生在三个点上;

  • 客户端设备上的直接连接可能会失败(即移动服务或WiFi网络丢失)
  • 连接可能直接在服务器上发生故障(例如,服务器所连接的网络交换机断电)--这在现代容错的虚拟数据中心中是极不可能的.
  • 客户端和服务器之间的某个其他点上的连接可能会失败.

现在,我们需要考虑每个端点在这三种情况下"看到"的情况,并了解TCP连接具有很强的弹性,并且需要相当长的时间来报告由于分组丢失而导致的连接故障.

在第一种情况下,客户端网络堆栈发现网络连接在物理上丢失,并可以快速报告所有网络连接上的错误(这是您在应用程序中看到的).然而,在服务器端,TCP重试过程意味着连接将在一段时间后被视为丢失(客户端设备无法发送关闭连接的TCP包,因为它没有网络连接……)

在第二种情况下,情况将相反;服务器将立即知道网络出现故障(但不能告诉客户端),而客户端最终会超时.

在第三种情况下,两端都将经历最终的超时.

第一种情况最有可能是由于移动网络的性质(事实上,您声称是客户端丢失了连接).

当客户端连接时,服务器启动事务,并可能在很短的时间内完成事务,可能只有几秒或几秒,但肯定比服务器从失败的客户端连接接收到TCP超时所需的时间要短.

现在只剩下Rob在他的 comments 中描述的情况了.服务器已完成工作,但客户端在收到服务器回复之前已收到网络故障消息.

您可以在服务器上修复此问题.例如,它可以延迟提交事务,直到响应成功传递到客户端.如果服务器在向客户端发送响应时收到网络错误,它可以回滚事务.当然,在提交事务之前但在提交响应之后仍然存在服务器故障的可能性(但这通常不太可能);真正的幂等处理是复杂的.

或者,您可以实现一个流程,让客户端在发生网络错误后判断服务器的状态,以确定事务是已完成还是必须重试.

Ios相关问答推荐

如何在SwiftUI中扩展 colored颜色 超出顶部边缘

带有动画层的UIView表示不会在工作表中设置动画

如何在SwiftUI ScrollView中zoom 中心项目?

如何在wiftUI中管理导航栈?

XcodeCloud生成失败,返回";ci_pre_xcodeBuild.sh是可执行文件,但退出时返回2个退出代码.";

无法添加以供审阅-Xcode 15.0.1

Xcode 15阻止我的应用程序运行:由于实时模式录制的高比率,丢失了1条日志(log)/路标消息?

当虚拟对象附加到其网格时,如何刷新创建 ARView 的 SwiftUI UIViewRepresentable?

圆角矩形路径上的蛇形动画

使用 SwiftUI 显示多个 VNRecognizedObjectObservation 边界框时偏移量错误

从 PHAssets 生成图像时,iOS 应用程序因内存问题而崩溃

从iOS键盘输入时Flutter TextField输入消失

在 SwiftUI 中将 TextEditor 文本计数连接到 ProgressView

分析应用程序版本时出错 - Apple 提交到store

使用 Vim 代替(或与)Xcode 进行 iOS 开发

iOS 中的 [Class new] 和 [[Class alloc] init] 有什么区别?

有没有办法在 xib 文件中的视图和顶部布局指南之间添加约束?

由于 NSInvalidUnarchiveOperationException 导致 iOS11 WKWebview 崩溃

如何缩小 UIImage 并使其同时变得清晰/锐利而不是模糊?

呈现和关闭模态视图控制器