前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CocoaAsyncSocket源码解析---终

CocoaAsyncSocket源码解析---终

作者头像
CC老师
发布2023-03-23 18:56:59
5350
发布2023-03-23 18:56:59
举报
文章被收录于专栏:HelloCode开发者学习平台

为译者CocoaAsyncSocket ,这篇主要介绍了:disconnect 注:由于该框架源码篇幅过大,且有大部分相对抽象的数据操作逻辑,尽管楼主竭力想要简单的去陈述相关内容,但是阅读起来仍会有一定的难度。不是如果想诚心学习IM相关知识,在这里就可以离场了......

插座与的APN

iOS- CocoaAsyncSocket源码解析(Connect上) iOS- CocoaAsyncSocket源码解析( 阅读上) iOS- CocoaAsyncSocket源码解析(阅读下) iOS- CocoaAsyncSocket源码解析(写)

注:文中涉及代码比较多,建议大家结合源码一起阅读比较容易能加深理解。这里有楼主标注好注释的源码,有需要的可以作为参照:CocoaAsyncSocket源码注释

正文

这里面还是常规操作,对我们关闭任务的处理:同步关闭

disconnect核心代码

  • 添加关闭连接超时,先关闭了正在执行的读写任务,同事移除读写队列,我们的提前缓冲区preBuffer也进行reset
  • 相应事件流的关闭,释放,制空
  • SSL上下文关闭,释放
  • 针对三种不同类型插座进行关闭释放
  • 都去取消的烃源
  • 代理回调关闭状态

如果大家想玩转插座还有两个重要点还是需要掌握的

  • 乒乓机制
  • 重连

简单的来说,心跳就是用来检测TCP连接的双方是否可用。那又会有人要问了,TCP本身不是就自带一个KeepAlive机制吗? 这里我们需要说明的是TCP的KeepAlive机制只能保证连接的存在,但是并不能保证客户端以及服务端的可用性。比如会有以下一种情况:

某台服务器因为某些原因导致负载超高,CPU 100%,无法响应任何业务请求,但是使用TCP探针则仍旧能够确定连接状态,这就是典型的连接活着但业务提供方已死的状态。

这个时候心跳机制就起到作用了:

  • 我们客户端发起心跳平(一般都是客户端),假如设置在10秒后如果没有收到回调,那么说明服务器或者客户端某一方出现问题,这时候我们需要主动断开连接。
  • 服务端也是一样,会维护一个插座的心跳间隔,当约定时间内,没有收到客户端发来的心跳,我们会知道该连接已经失效,然后主动断开连接。

参考文章:为什么说基于TCP的移动端IM仍然需要心跳保活?

其实做过IM的小伙伴们都知道,真正我们需要心跳机制的原因其实主要的英文在于国内运营商NAT超时。

究竟那么什么的英文NAT超时呢?

原来这是因为IPV4引起的,我们上网很可能会处在一个NAT设备(无线路由器之类)之后 .NAT设备会在IP封包通过设备时修改源/目的IP地址。对于家用路由器来说,使用的是网络地址端口转换(NAPT),它不仅改IP,还修改TCP和UDP协议的端口号,这样就能让内网中的设备共用同一个外网IP。举个例子,NAPT维护一个

类似下表的NAT表:

NAT设备会根据NAT表对出去和进来的数据做修改,192.168.0.3:8888比如将发出去的封包改成120.132.92.21:9202,外部就认为他们是在和120.132.92.21:9202通信。同时NAT设备会将120.132.92.21:9202收到的封包的IP和端口改成192.168.0.3:8888,再发给内网的主机,这样内部和外部就能双向通信了,但如果其中192.168.0.3:8888== 120.132.92.21:9202这一映射因为某些原因被NAT设备淘汰了,那么外部设备就无法直接与192.168.0.3:8888通信了。

我们的设备经常是处在NAT设备的后面,比如在大学里的校园网,查一下自己分配到的IP,其实是内网IP,表明我们在NAT设备后面,如果我们在寝室再接个个由器,那么我们发出的数据包会多经过一次NAT。

国内移动无线网络运营商在链路上一段时间内没有数据通讯后,会淘汰NAT表中的对应项,造成链路中断。

而国内的运营商一般NAT超时的时间为5分钟,所以通常我们心跳设置的时间间隔为3-5分钟。

接着我们来讲讲乒乓机制:

很多小伙伴可能又会感觉到疑惑了,那么我们在这心跳间隔的3-5分钟如果连接假在线(例如在地铁电梯这种环境下)。那么我们岂不是无法保证消息的即时性么?这显然是我们无法接受的,所以的业内解决方案的英文采用双向的PingPong机制。

当服务端发出一个Ping,客户端没有在约定的时间内返回响应的ack,则认为客户端已经不在线,我们这时Server端的会主动断开Scoket连接,改并且由APNS推送的方式发送消息。 同样的是,当客户端去发送一个消息,因为我们迟迟无法收到服务端的响应的ACK包,则表明客户端或者服务端已不在线,我们也会显示消息发送失败,断开并且Scoket连接。

记得还我们之前CocoaSyncSockt的例子所讲的电子杂志消息超时就断开吗?它其实就是一个PingPong机制的客户端的实现。我们每次可以在发送消息成功后,调用这个超时读取的方法,如果一段时间没收到服务器的响应,那么说明连接不可用,断开则Scoket连接

  • 最后就是重连机制:

理论上,自己我们去主动断开的Scoket连接(例如退出账号,APP退出到后台等等),不需要重连。其他的连接断开,我们都需要进行断线重连。一般解决方案是尝试重连几次,如果仍旧无法重连成功,那么不再进行重连。

CocoaAsyncSocket源码解析的过程,还是收货颇丰的!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-11-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 逻辑iOS技术号 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 正文
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档