Files
knowledge-kit/Chapter7 - Geek Talk/7.8.md
2020-02-25 17:46:51 +08:00

17 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# iOS 隔了较久时间推送变得缓慢
![](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/442e4085cf4b8f62c7ad359343c5f155_hd.png)
这个图是重点描述了真实消息推送的过程App开发者或者第三方推送平台的服务器\(图例中的Provider\)向APNs发起推送指令的请求**推送指令包含了要下发设备的device-token和要下发的内容payload两部分**由APNs根据device-token\(device-token是APNs生成颁发的\)将payload下发到设备上再由设备路由给具体的App。我们这里只关注第一步Provider到APNs的过程即Provider的服务器和APNs的服务器通信的过程。APNs要求Provider首先与APNs建立一条长连接Provider通过长连接可以将单个或者一批device-token发送给APNs这个过程中只要有一个device-token是不合法的\(错误或者失效\)那么APNs就会主动断掉Provider到APNs的长连接Provider探测到连接断掉之后需要重新建立连接跳过上次失败的device-token从下一个device-token接着发送。这个过程循环往复直至将本次要发送的所有的device-token都推送到APNs那么这次推送任务就算完成了。剩下的工作就是APNs将消息下发到具体设备了APNs将消息下发给设备这个过程不管是App开发者直接和APNs打交道、亦或是第三方推送服务器和APNs打交道我们都是无法控制的了所以推送的重点就是图例中的第一步Provider到APNs之间的通信了。
接下来我们回到问题就是为什么隔了很久之后再去做推送发送过程会变得非常慢。其实经过上面的解释大家就应该能把原因猜的差不多了就是因为长时间不发送的话会有很多设备上的device-token已经无效了比如设备卸载了App或者系统版本升级过导致device-token变化了或者是其它导致APNs认为device-token不合法的原因。总之时间长了不合法的device-token就会变多在上面的章节中也提到Provider和APNs的服务器建立长连接进行消息发送时如果碰到了不合法的device-tokenAPNs就会断掉长连接需要Provider重新建立连接。失效的device-token多了那么断掉连接-重新连接的次数就会增多,每次重新连接都需要耗费时间,甚至如果频繁的断掉-重连APNs有时候会被APNs认为是一种DoS攻击\(APNs官网这么解释但是具体判定的算法没有透露\)会导致短时间内APNs拒绝Provider的连接这种情况下不管是App开发者自己直接和APNs打交道还是第三方推送平台和APNs打交道碰到这种情况都是无能为力的。 只能被动的接受“断掉-重连”的工作方式,因此整个发送过程会特别缓慢。 所以总结下来长时间不发送消息再次发送的时候必然会出现推送缓慢的情况原因就是无效的device-token越来越多导致不断的“断开-重连”。所以在本文开头的时候就提到过如果App开发者亲自使用过APNs服务的话对这种现象必定是非常熟悉了也会见怪不怪了。 如果是两次发送任务之间隔得时间不是太长两次发送期间失效device-token不是那么多的时候速度还是比较快的。
那么既然失效的device-token是导致发送变慢的主要原因那么开发者朋友们肯定会想能不能提前判断出失效的device-token直接从发送列表中剔除掉这些失效的token。其实APNs是提供这样的feedback接口的调用这个接口会得到一批失效的device-token列表。那么是不是在一次发送之前去调用一下这个接口获取到无效的device-token在发送的过程中剔除掉这些无效的device-token就能加快发送速度呢 其实不然因为feedback接口是一个后验的接口即只有一次推送任务结束之后APNs才会把该次失效的device-token更新到feedback接口的返回结果里面。如果你在一次推送任务前调用feedback接口那么得到的失效device-token是基于上一次推送任务的结果的两次推送任务之间发生的失效的device-token是无法提前获取到的只能等当次推送任务结束之后才可以去获取新的失效token列表。
问题到这里就解释清楚了,那么碰到这种情况,我们该如何提升发送速度呢? 这里我们给大家讲讲友盟推送平台针对这种情况做的一些优化相比App开发者直接连接APNs做推送还是有一定的优势:\) 解决方法很简单就是友盟有很多台连接APNs的服务器每个服务器我们又会开很多个线程去和APNs做连接所以在并发度上会有较大的优势。所以针对一次发送任务使用友盟平台做推送速度肯定会比自己直接连接APNs有优势这个也是不少开发者放弃了直接和APNs打交道而是选择友盟推送来实现iOS推送的原因之一。