默认
发表评论 4
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
iOS 用gcdAsyncSocket开发IM关于timeout的问题
阅读(51999) | 评论(4 收藏 淘帖1
1.客户端向服务端发一条消息,想知道服务端已经收到了,所以要求服务端收到后发一个“ACK包”回来,如果客户端n秒内没收到,就重发这条消息。因此我客户端置:[socket readDataWithTimeout:n tag:0],然后在读超时的代理中进行重发。
2.但因为是IM聊天,所以服务端也会主动把别的客户端发给我的消息转发过来,所以要readDataWithTimeout:-1不设置超时一直等待。

现在的问题:
在连接、登录鉴权之后,我就readDataWithTimeout:-1等待接服务器消息。但当我发消息给别人,readDataWithTimeout:n,但接收ACK是用readDataWithTimeout:-1来完成的,导致n秒后会告诉我读取超时。
经查资料得知,gcdAsyncSocket源码中是用一个队列来管理read任务的,一有回调就取队列的第一个read。所以说我就无法设置多种timeout了?而且tag参数也无法让我取得想要的read任务。那是不是要把timeout都统一成-1,然后根据个别需要ACK的业务另外开一个计时器去管理超时重发的问题?还是说有别的做法呢?

即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

上一篇:IM客户端收到消息后,需要按接收到的时间进行排序,如何 实现比较好?下一篇:写一个IM服务端需要具备哪些技术能力?

本帖已收录至以下技术专辑

推荐方案
评论 4
首先,你对TCP的理解可能是有问题的:
你跟服务器建立TCP连接后,这条连接就是个全双工的长连接,就像一条管道,它的出和入可同时进行互不干扰。你所有的数据发出,都只是通过这条水管往外送而已,基于TCP协议栈的设计原理,TCP的底层数据都是这条水管里排队同步往外发的(即使你上层封装成了伪异步,看字面意思就知道了:AsyncSocket)。所以你理解的要加不同的readDataWithTimeout:n什么readDataWithTimeout:-1,这就很诡异了,“read”即表示管道的接收方向,同一条管理,怎么可能开多于一个“read”?

你的设计上应该这样优化:
  • 1)你的超时机制,应该是自已写一个守护线程,自动来检查你发出的消息,当发现超时时由这个线程来决定何时重传,跟TCP通道的越时机制无关(也不应该有关);
  • 2)TCP的收、发数据是一个统一且应是唯一的实例方式来使用,且应该是跟业务逻辑无关的,即它们只是用来收和发数据的通道,回归到网络编程的本质。额外的逻辑都通过收到或发出数据后的回调来触发你自已的业务逻辑。

以上这样的设计,就可以让你的数据传输层跟业务层解耦,不然你的代码是越写越难写,越写越糟糕,以致于代码失控到你自已也不能预见会发生什么bug。因为网络编程本身就存在网络通信层的复杂性,而你再加入你业务逻辑层的复杂性,这样的叠加,代码想不糟糕都不可能。

以上是经验之谈,如果你现在还太能理解,那表示你还需要更多的实践。

你也可以参考一下MobileIMSDK,你可能需要的超时机制可以参考它的实现。

另外,论坛里的这些TCP的文章,你可以看看:
TCP/IP详解 - 第17章·TCP:传输控制协议
TCP/IP详解 - 第18章·TCP连接的建立与终止
TCP/IP详解 - 第21章·TCP的超时与重传
通俗易懂-深入理解TCP协议(上):理论基础
通俗易懂-深入理解TCP协议(下):RTT、滑动窗口、拥塞处理
理论经典:TCP协议的3次握手与4次挥手过程详解
理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程
不为人知的网络编程(一):浅析TCP协议中的疑难杂症(上篇)
不为人知的网络编程(二):浅析TCP协议中的疑难杂症(下篇)
不为人知的网络编程(三):关闭TCP连接时为什么会TIME_WAIT、CLOSE_WAIT
不为人知的网络编程(四):深入研究分析TCP的异常关闭
引用:JackJiang 发表于 2017-10-06 11:08
首先,你对TCP的理解可能是有问题的:
你跟服务器建立TCP连接后,这条连接就是个全双工的长连接,就像一条 ...

确实好像是理解错了,谢谢你的解答。
引用:JackJiang 发表于 2017-10-06 11:08
首先,你对TCP的理解可能是有问题的:
你跟服务器建立TCP连接后,这条连接就是个全双工的长连接,就像一条 ...

大神  请教下GCDAsyncSocket  跟SRWebSocket  有什么区别   如果开发的话选哪个好一些
引用:hglaonanhai 发表于 2018-05-12 18:09
大神  请教下GCDAsyncSocket  跟SRWebSocket  有什么区别   如果开发的话选哪个好一些

GCDAsyncSocket不支持WebSocket吧,你的SRWebSocket字面上看是针对WebSOcket协议的
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部