默认
发表评论 7
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
[已回复] 想咨询一下MobileIMSDK消息发送成功送达服务器的判断问题
阅读(41314) | 评论(7 收藏 淘帖1
我现在在开发IOS的IM客户端,在客户端A生成fp,然后使用这个FP发消息msg1给客户端B,同时会把msg1保存到sqlite中,在msg1的数据里会有一个字段叫做sendFlag,用来表示此条消息的送达状态。0表示正在发送中,1表示服务端返回确认到达即IOS 的messagesBeReceived执行了,2表示消息发送失败,即messagesLost执行了。

        但是我使用时发现,如果我发送完一条消息后,如果客户端按HOME切出去了,这时服务端的消息返回了。客户端就接收不到确认了,以后这条聊天记录会永远显示正在发送中的状态。或者没切出去,但比如说出现了什么其它异常,导致客户端的MessageQoSEvent没正常执行,都会使数据库里这条消息的发送状态永远是0。用户在聊天界面的体验就不太好了。

        我想过设置超时时间,就是如果这条消息发送时间跟当前时间比对如果超过几分钟后状态还是0,就给它设定成未送达。这样会不会不是特别好?有什么好办法来解决这个问题吗?

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

标签:MobileIMSDK
上一篇:[已回复] MobileIMSDK v3.0客户端sendCommonData服务器收不到数据?下一篇:[已解决] 求教MobileIMSDK服务器连接后无法监听返回消息的问题

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

推荐方案
评论 7
你考虑的问题确实是有一定几率存在,但可以肯定的是,这种情况属极小概率事件,用户正常聊天情况下不会有聊聊着就莫名其妙的按home了,而且即使ios的APP home到后台之后,还有个5秒的缓冲,加上自已按home这样的动作时间,从用户这一条消息到发出,到APP被ios关闭,理论上存在5到8秒左右和时间缓冲,而真正网络不好的情况下,这几秒中的时间已经开始了一到2个包的重传(加上自已发的那次,QoS一共提供了2到3次的发送保证),理论上除非网络很差,都可以送达,而且ACK也能正常回来,如果APP在被关闭之前真的送不到或者收不到应答,这也只能说明网络真的很差,判定为丢包很正常。总之,做为一个真实用户的正常操作来说,基本上不会有太大的体验问题。

不过,存在一种情况就是万一APP因为其它业务代码导致了崩溃,那么ACK也没办法收到,QoS线程在下次重启时已把上次的send检查队列给重置了,崩溃前的现场恢复不了,是有可能存在你说的一直处于“发送中”的状态。

解决这个“发送中”的状态,有两个方法:
1)方法1是直接不理会,因为概率实在太小,分散到整个APP中的用户的话,几率更小,就像QQ的原则一样——允许万有一失的可能性存在,那么为了简单,你可以不保存这个状态到sqlite中(相当于存放于sqlite中的消息只是作为记录,无状态);
2)方法2跟你说的思路有点类似,但更优雅一些,就是把QoSSend线程中的发送保证队列从内存中持久化到NSUserDefault中(因为对于用户来说,正常聊天情况下处于此列表中的消息基本上最多是个位数,所以持久化到NSUserDefault中没有什么性能损耗和负担),等到下次重启APP时,QoSSend线程init时把这个列表从持久化中恢复出来,让它自已来继续QoS逻辑(上次没收到ACK应答的,过了这么久,这次肯定会被判定为未送达了),那么从应用层的代码实现来说,你不需要专门针对性修改任何代码,实现是优雅的,也达到了你的目的,但唯一有点麻烦的是自已需要稍微改造一下MobileIMSDK 的QoSSend线程的源码,无非就是加一个保存到NSUserDefault和从NSUserDefault中恢复的代码就行了(这个优化我考虑在下个版本的MobileIMSDK加进去,你自已可以提前实现一下,以前有考虑过这个问题,但我之前认为数据持久化对于MobileIMSDK这种高度提炼的SDK级框架来说不优雅和也不轻量,所以就没有做),基本上是可以解决你说的问题的——理论上再也不可能存在有消息永远处于未送达状态了。
引用:JackJiang 发表于 2017-11-27 11:42
你考虑的问题确实是有一定几率存在,但可以肯定的是,这种情况属极小概率事件,用户正常聊天情况下不会有聊 ...

多谢您的回复。这种情况在我更新到软件里后不久,就在一个用户使用时发生了。消息已经从A到B了,结果A还是没有成功回调,状态还是0。当然他特意给我拍成视频发给我看的。两个手机,B已经收到消息了,A的那条消息旁边的发送状态图标还是loading中。我自己测试时完全没发生过这种情况,而且用户也说她好像没按HOME键。我感觉我现在的用法肯定还会有这种情况发生。
您提供的方法二倒是一个办法,我先试试看。
我在做聊天视频发送和图片发送时,视频上传和图片上传的进度信息保存到了NSUserDefault里。因为这个进度的需求其实跟送达的需求也差不多,但考虑这个进度变化性太多,不适合放到数据库里就放在NSUserDefault里了。
引用:heavenK 发表于 2017-11-27 14:20
多谢您的回复。这种情况在我更新到软件里后不久,就在一个用户使用时发生了。消息已经从A到B了,结果A还 ...

你按照我的建议里第2个方法去实现,改动很小的,试试看,如果是大改动,那你一定是理解错了,再整理一下思路。
引用:JackJiang 发表于 2017-11-27 14:25
你按照我的建议里第2个方法去实现,改动很小的,试试看,如果是大改动,那你一定是理解错了,再整理一下 ...

好的,我明白你的方法的意思了。我先试试看。
引用:JackJiang 发表于 2017-11-27 11:42
你考虑的问题确实是有一定几率存在,但可以肯定的是,这种情况属极小概率事件,用户正常聊天情况下不会有聊 ...

我在修改完SDK,运行时报错了。在报错输出时发现,Qos的队列没法保存到NSUserDefaults里,因为队列里的类型是自定义的协议类型,需要用到archiver。相当于先编码才能保存。这样的话会不会比较影响性能啊?
引用:heavenK 发表于 2017-11-28 11:11
我在修改完SDK,运行时报错了。在报错输出时发现,Qos的队列没法保存到NSUserDefaults里,因为队列里的类 ...

你转JSON 字串后保存嘛,或者找个更高效一点的方法。理论上这基本不会影响体验,你可以按照真实的用户习惯,再牛逼的人发一条消息从打字到点按钮发出也要几秒种,况且恢复队列只有app重启时做一次。

你客观的评估一下,别凭感觉,我认为技术上一定是可行的。
引用:JackJiang 发表于 2017-11-28 11:37
你转JSON 字串后保存嘛,或者找个更高效一点的方法。理论上这基本不会影响体验,你可以按照真实的用户习 ...

好的,也有道理,用户发消息没道理1秒发好几十条。我先用上测试看看。
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部