HTTP

多次上传文件失去连接('The network conn

2017-11-02  本文已影响12人  zmj27404

1.引子

近期项目开发过程中,有个需求是文件断点续传,同时上传数量为5。按照正常上传方法,采用NSOperationQueue作为任务队列,NSOperation作为任务,添加到NSOperationQueue,具体实现后面再写。说说其中发生的奇怪的问题,当一个操作在多次点击暂停上传后,开始上传,终端出现

Nw_connection_write_close 25 connection is not ready,sending error callback

__tcp_connection_write_eof_block_invoke write close callback receive error:[57] socket is not connected

结果就是不管怎样,重新启动,切换网络环境都不起任何作用,上传一直处于失败状态,即使重新从头开始上传,上传到那一段还是会失败。且报的错是<strong>“Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." "</strong>,但其实网络是相通的,接口调用都没有问题。

2.原因分析

经过Google,StackOverFlow,baidu后,查阅关键字

Nw_connection_write_close 25 connection is not ready,sending error callback

第一次试了修改"<strong>Accept-Encoding:deflate</strong>",然后在同样测试环境下进行测试,结果和之前一样,未能够修复;第二个方法是让服务器修改"<strong>Keep-Alive:timeout=5, max=100</strong>",或者更多,由于服务器是另外一个项目,没有权限进行尝试,况且别的项目没有说过这种情况,所以这种方法就不得而知,是否行得通;第三种方法也是我的解决方案,其中有这样一段话:

<strong>For this to work you must make sure that you use the right HTTP method for each request. There are two ways this can go wrong</strong>:

  1. If you use a non-idempotent HTTP method for an idempotent request, NSURLSession will not retry the request even though it could safely do so. This isn’t a serious problem; you can just retry the request yourself.
  2. If you use an idempotent HTTP method for a non-idempotent request, that’s very bad. NSURLSession might retry the request even though doing so is unsafe. The only valid solution here is to change your request to use a different HTTP method, which may require server-side changes.

翻译:

<strong>为此,您必须确保为每个请求使用正确的HTTP方法。 有两种方法可能会出错:</strong>

  1. 如果您使用非幂等HTTP方法进行幂等请求,NSURLSession即使可以安全地执行此操作,也不会重试该请求。 这不是一个严重的问题; 您可以自己重试请求。
  2. 如果对非幂等请求使用了幂等的HTTP方法,这是非常糟糕的。 NSURLSession可能会重试该请求,即使这样做是不安全的。 唯一有效的解决方案是更改您的请求以使用不同的HTTP方法,这可能需要服务器端更改。

到了现在我才知道HTTP有个幂等性,查阅资料

  1. 一个HTTP方法是幂等的,指的是同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的。换句话说就是,幂等方法不应该具有副作用(统计用途除外)。在正确实现的条件下,GET,HEAD,PUT和DELETE 等方法都是幂等的,而 POST 方法不是。所有的 safe 方法也都是幂等的。
  2. 幂等性只与后端服务器的实际状态有关,而每一次请求接收到的状态码不一定相同。例如,第一次调用DELETE 方法有可能返回 200,但是后续的请求可能会返回404。DELETE 的言外之意是,开发者不应该使用DELETE方法实现具有删除最后条目功能的 RESTful API。

我上传使用的请求是POST,属于非幂等性,上传中多次点击后再次上传会导致错误的更新。于是我改成幂等性且与POST请求功能一致的PUT请求,PUT是幂等性方法。经过多次实践测试后,没有出现<strong>失去连接("The Connect was Lost")</strong>的提示,并且之前上传失败的连接在修改为PUT请求后也能够继续上传。问题得到解决。

3.后续

经过这次Bug学习,了解到HTTP幂等性与非幂等性特性。也学习了POST、PUT请求的区别,对于这种有多次交互的请求的方法可以采用PUT请求试试哦!

上一篇下一篇

猜你喜欢

热点阅读