默认
发表评论 20
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
[已回复] MobileIMSDK开发的IM中实现回执功能的问题求助
阅读(74346) | 评论(20 收藏 淘帖
目前在写回执,移动端向客户端发送消息,客户端向移动端发送回执,请问:在【MobileIMSDK框架层协议:用户通用数据转发请求】(ProtocalType.C.FROM_CLIENT_TYPE_OF_COMMON$DATA)  里面调用了一下ACK消息应答包的逻辑对吗?很盲目,没有思路,求指教!!

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

标签:MobileIMSDK
上一篇:[已回复] MobileIMSDK做的im登录时服务端返回的错误码意义疑问下一篇:[已解决] 我的IM在springboot启动时同时启动MobileIMSDK导致被阻塞问题
推荐方案
评论 20
你所说的回执,是这个帖子里《IM群聊消息的已读回执功能该怎么实现?》,这个已读未读这个东西吗?
引用:JackJiang 发表于 2018-06-13 10:06
你所说的回执,是这个帖子里《IM群聊消息的已读回执功能该怎么实现?》,这个已读未读这个东西吗?

不是,只是消息发送成功的回执,目前每次移动端发送聊天消息都会发送三遍。
引用:xushuhua 发表于 2018-06-13 10:09
不是,只是消息发送成功的回执,目前每次移动端发送聊天消息都会发送三遍。

理论上不可能,除非你改动了框架的代码,框架里把应答都给你处理好了,具体你看看这个贴子里的讨论:
[已回复] 当MobileIMSDK的客户端收不到对方的ACK应答包时会发生什么?
引用:JackJiang 发表于 2018-06-13 10:58
理论上不可能,除非你改动了框架的代码,框架里把应答都给你处理好了,具体你看看这个贴子里的讨论:
《 ...

        case ProtocalType.C.FROM_CLIENT_TYPE_OF_COMMON$DATA:
                    {
                            logger.info("[IMCORE-netty]<< 收到客户端"+remoteAddress+"的通用数据发送请求.");
                            //向客户发送一个IM回执,type=2
                            //logicProcessor.processACK(pFromClient, remoteAddress);
                            // 开始回调
                            if(serverEventListener != null)
                            {
                                    if(!OnlineProcessor.isLogined(session))
                                    {
                                            LocalSendHelper.replyDataForUnlogined(session, pFromClient, null);
                                            return;
                                    }
       
                                    // 【C2S数据】客户端发给服务端的消息
                                    if("0".equals(pFromClient.getTo()))
                                            logicProcessor.processC2SMessage(session, pFromClient, remoteAddress);
                                    // 【C2C数据】客户端发给客户端的消息
                                    else
                                            logicProcessor.processC2CMessage(bridgeProcessor, session
                                                            , pFromClient, remoteAddress);   //为网页端客户端发送消息并保存数据
                            }
                            else
                            {
                                    logger.warn("[IMCORE-netty]<< 收到客户端"+remoteAddress+"的通用数据传输消息,但回调对象是null,回调无法继续.");
                            }
                            break;
                    }

这是【MobileIMSDK框架层协议:用户通用数据转发请求】通道,但是并没有服务器接收到数据的回执,然后我是想着在服务器接收之后加个回执,但是并没有控制住每次都发送三次的频率。求指教

引用:xushuhua 发表于 2018-06-13 11:38
case ProtocalType.C.FROM_CLIENT_TYPE_OF_COMMON$DATA:
                    {
                            logger.info("

首先,你一行代码都不要动的情况下,MobileIMSDK框架算法算动实现了回执ACK的功能,这个回执你能在我4楼给出的贴子里告诉你的回调里收到这个回执回调通知。

然后,框架已以实现了回执的情况下,你是在纠结什么?你要改这个回执算法呢,还是说这个回执在你测试的时候没有生效?你的描述比较混乱,没太看明白
引用:JackJiang 发表于 2018-06-13 13:38
首先,你一行代码都不要动的情况下,MobileIMSDK框架算法算动实现了回执ACK的功能,这个回执你能在我4楼 ...

大佬,我客户端向服务端发送消息,怎样知道发送成功了
引用:xushuhua 发表于 2018-06-13 20:58
大佬,我客户端向服务端发送消息,怎样知道发送成功了

你看一眼我在4楼回复你的贴子里的内容。
引用:JackJiang 发表于 2018-06-13 21:04
你看一眼我在4楼回复你的贴子里的内容。

@Override
        public boolean onTransBuffer_C2C_RealTimeSendFaild_CallBack(final String userId,
                        final String from_user_id, final String dataContent,  String fingerPrint, final int typeu)
        {
                //消息失败做离线消息处理
                int ctype=0;
                 String fp="";
                 System.out.println("typeu:"+typeu+" 指纹码:"+fingerPrint);
                //存储消息
                if(typeu/10==2){
                //来源用户id   from_user_id ,发送给用户id  to_user_id,内容 content,发送类型    utype ,发送时间 send_time,聊天类型:1单聊 , 2群聊   ctype,   1离线消息,0历史消息:sendStatus
                        ctype=2;
                        fp=fingerPrint+"#"+userId;
                }else{
                        ctype=1;
                        fp=fingerPrint;
                }
                final int c=ctype;
                final String fingerPrints=fp;
                executes.submit(new Runnable(){
                        @Override
                        public void run() {
                                try {
                                        MessageService.ser.saveMessage(fingerPrints,from_user_id, userId, dataContent, typeu, c, 1);
                                        System.out.println(fingerPrints+"##########################################################失败回调");
                                } catch (Exception e) {
                                        e.printStackTrace();
                                }
                        }
                });
                logger.debug("【DEBUG_回调通知】[typeu="+typeu+"]客户端"+from_user_id+"发给客户端"+userId+"的消息:str="+dataContent
                                +",因实时发送没有成功,需要上层应用作离线处理哦,否则此消息将被丢弃.");
                        return false;
        }
我真的有看,这个代码中MessageService.ser.saveMessage(fingerPrints,from_user_id, userId, dataContent, typeu, c, 1);是用来保存离线,并且里面有写个推送,也就是回调失败三次会触发推送,但是如果改了返回结果,不会进行再次回调触发不了推送。请问怎么解决呢?

引用:xushuhua 发表于 2018-06-14 09:38
@Override
        public boolean onTransBuffer_C2C_RealTimeSendFaild_CallBack(final String userId,
                        f ...

你的这个思路并不是最佳方式,离线消息无论如何应该先落地(就是存到数据库或者redis这种能持久化的东西里,而不致于被丢失),然后再来推送,因为无论是自已实现推送还是用第3方(比如ios的APNS推送通道),都不能保证百分百推的到或者不丢,也不是他们的义务),都应该是自已保证数据的可靠性。你推送前先存起来,推送成功再删除,这就不存在你说的问题,也比你现在想的这样简单多了。
引用:JackJiang 发表于 2018-06-14 10:18
你的这个思路并不是最佳方式,离线消息无论如何应该先落地(就是存到数据库或者redis这种能持久化的东西 ...

再请教您几个问题:1.A给B发送消息,B不在线,调用了onTransBuffer_C2C_RealTimeSendFaild_CallBack(),给A一个回执.伪发送这个回执不是报文的第2步吧,第2步不应该是在服务器收到A发送的消息的同时回执给A表示服务器接收成功吗?
2.请问第2步回执是在哪个方法里?A若收到6步报文的第2步,B不在线,服务器还会给B发送三次吗?
引用:xushuhua 发表于 2018-06-14 12:02
再请教您几个问题:1.A给B发送消息,B不在线,调用了onTransBuffer_C2C_RealTimeSendFaild_CallBack(), ...

MobileIMSDK中,当进入回调onTransBuffer_C2C_RealTimeSendFaild_CallBack这个方法的时候,意味着B不在线,那这个回执B是不可能发的出来(除非闹鬼了),但是服务端帮它把这个消息持久化存储起来了,也就相当于被B收到了(只是B还没有看而已),所以由服务端代发回执这个逻辑没有问题,总不能告诉A说消息送不到,那不就意味着不支持离线消息了吗。你试着想想如果你来写这个逻辑,你该怎么处理?就明白了
引用:JackJiang 发表于 2018-06-14 14:51
MobileIMSDK中,当进入回调onTransBuffer_C2C_RealTimeSendFaild_CallBack这个方法的时候,意味着B不在线 ...

这个我是可以理解的,若是对方不在线会发送为A一个伪应答包。现在是尝试向B发送三次失败之后进行推送和向A发送伪应答包冲突了,是不是我的推送逻辑有问题呢?
如果我第一次回调之后就给A一个伪应答包就不会向B发送三次,也就触发不了推送。
引用:xushuhua 发表于 2018-06-14 17:43
这个我是可以理解的,若是对方不在线会发送为A一个伪应答包。现在是尝试向B发送三次失败之后进行推送和向 ...

是的,你的推送逻辑有问题,应答过去了,对方的QoS机制就不会重传了
引用:JackJiang 发表于 2018-06-14 17:52
是的,你的推送逻辑有问题,应答过去了,对方的QoS机制就不会重传了

那我应该什么时候触发推送呢?求大神指教
引用:xushuhua 发表于 2018-06-14 17:58
那我应该什么时候触发推送呢?求大神指教

你什么也不用管,只要服务端的离线回调里进行推送就行了(前提是该离线存储的还是要存储,推送只是辅助手段,因为推送的东西对方可能收不到啊,这受推送通道的影响,因为推送服务方不一定能保证百分百到达嘛),因为框架判定的需要离线存储的代码,就表示对方不在线(原因可能是对方真不在线,或在线但是app被杀死、也或者是app已退到后台等情况),那么此时就是你推送上场了。
引用:JackJiang 发表于 2018-06-14 18:04
你什么也不用管,只要服务端的离线回调里进行推送就行了(前提是该离线存储的还是要存储,推送只是辅助手 ...

我今天改了改在离线回调的时候进行推送,但是出现了,对方再线也进行推送的情况,发送三次的机制也失去了作用。
引用:xushuhua 发表于 2018-06-14 19:56
我今天改了改在离线回调的时候进行推送,但是出现了,对方再线也进行推送的情况,发送三次的机制也失去了 ...

为了保险,你应该多一重判断:如果OnlineProcessor.isOnline()==false时你再推不就万无一失了吗
引用:JackJiang 发表于 2018-06-14 20:04
为了保险,你应该多一重判断:如果OnlineProcessor.isOnline()==false时你再推不就万无一失了吗

嗯嗯  可以,非常感谢,但是又碰见一个问题,就是会重复推送好几遍。是有办法解决  但是我感觉您应该有更好的办法吧
引用:JackJiang 发表于 2018-06-14 20:04
为了保险,你应该多一重判断:如果OnlineProcessor.isOnline()==false时你再推不就万无一失了吗

大神 ,昨天给了我好多启发,非常感谢,单聊时跑通了,但是群聊有点儿问题,就是群聊的回执,现在的需求就是,A发送到群,现在想让A接收到发送成功的回执,A只需要接收一次回执不就行了嘛?是要群里的所有的人收到消息之后才进行回执嘛?因为没有发送完就接收到回执,会引起不再进行三次机制的发送。
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部