请选择 进入手机版 | 继续访问电脑版

默认
发表评论 15
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
[已回复] 求助MobileIMSDK中,客户端A发送消息给客户端B,怎么知道对方是否收到?
微信图片_20190926112604.png
## 场景描述> 客户端A 发送消息给 客户端B

## 业务逻辑
前提:客户端A和客户端B同时登录了并且同时在线
1. 客户端A发送消息(报文) 通过http方式发送到服务端
2. 服务端接收到客户端A的消息内容,如果是长文本,先记录到数据库返回消息ID给客户端B自行拉取否则直接发送消息给客户端B
3. 客户端B收到消息后返回应答码(ACK)告诉服务端说我已经收到了,服务端就会停止继续发送UDP报文给客户端B
4. 这个时候服务端已经知道客户端B已经收到数据,那如果更好的通知客户端A发出的消息已经被接收了?

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

标签:MobileIMSDK
上一篇:[已回复] 基于MobileIMSDK,网络切换、重连,remoteAddress变换,这种情况怎么解决?

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

推荐方案
评论 15
一句话描述一下:你这是打算为用户实现什么功能?
签名: 《马蜂窝旅游网的IM客户端架构演进和实践总结》:http://www.52im.net/thread-2796-1-1.html
引用:JackJiang 发表于 2019-09-26 12:28
一句话描述一下:你这是打算为用户实现什么功能?

我想用于标识消息已经发送出去并对方成功接收(消息已被客户端B接收)。
## 场景
1. 客户端A发出消息,APP显示转圈圈状态,如果我知道消息已经被B端消费,我就去除转圈状态否则显示红色标识说明消息未能发出。
引用:cotide 发表于 2019-09-26 12:36
我想用于标识消息已经发送出去并对方成功接收(消息已被客户端B接收)。
## 场景
1. 客户端A发出消息 ...

这个在MobileIMSDK是现成的,已经实现了完整的逻辑。

对于A端来说,收到了B端对于这条消息的ACK应答,就表示对方肯定收到了,这是最严谨和有效的方法。

你去看一下Android端的官方Demo里,MessageQoSEvent  这个接口的实现类,对方收到的消息,和超时重传后还无法送达的消息,都会通过这个接口的实现类告诉你,你就可以在这个类里去实现关闭你的转动的菊花(表示消息已送达),或者显示一红色小图标(表示消息未送达)
签名: 《马蜂窝旅游网的IM客户端架构演进和实践总结》:http://www.52im.net/thread-2796-1-1.html
引用:JackJiang 发表于 2019-09-26 14:31
这个在MobileIMSDK是现成的,已经实现了完整的逻辑。

对于A端来说,收到了B端对于这条消息的ACK应答, ...

我也看到MessageQoSEvent这个事件,但客户端A是通过http发送报文让服务端转发,这种情况。所以MessageQoSEvent的事件应该只在服务端触发吧? 这种情况客户端A没办法触发MessageQoSEvent
引用:JackJiang 发表于 2019-09-26 14:31
这个在MobileIMSDK是现成的,已经实现了完整的逻辑。

对于A端来说,收到了B端对于这条消息的ACK应答, ...

客户端(A)通过http发送消息让服务端去进行消息转发给客户端(B),如果这种情况MessageQoSEvent 应该是在服务端触发的,对于客户端(A)好像收不到任何消息关于Qos的反馈信息。
---------------
所以这里是不是服务端收到Qos反馈信息,需要给客户端A一些消息状态的信息,这里不是太懂该如何处理?
客户端(A)通过http发送消息让服务端去进行消息转发给客户端(B),如果这种情况MessageQoSEvent 应该是在服务端触发的,对于客户端(A)好像收不到任何消息关于Qos的反馈信息。
---------------
所以这里是不是服务端收到Qos反馈信息,需要给客户端A一些消息状态的信息,这里不是太懂该如何处理?
引用:cotide 发表于 2019-09-26 14:42
客户端(A)通过http发送消息让服务端去进行消息转发给客户端(B),如果这种情况MessageQoSEvent 应该是在 ...

你客户端A是通过http发送给客户端B?这是怎么玩出来的?

把客户A的发送代码、服务端的代发代码,贴出来,我看看你是怎么玩的
签名: 《马蜂窝旅游网的IM客户端架构演进和实践总结》:http://www.52im.net/thread-2796-1-1.html
引用:JackJiang 发表于 2019-09-26 15:15
你客户端A是通过http发送给客户端B?这是怎么玩出来的?

把客户A的发送代码、服务端的代发代码,贴出 ...

客户端A是通过http发送给服务端,进行转发到客户端B。客户端B的ACK应答码应该是返回给服务端的吧?
所以MessageQoSEvent 事件应该也是在服务端触发吧?

客户端A:

  /**
     * 发送私聊消息
     * @param message
     * @return
     */
    public void  send(PrivateMessage message, Callback callback)  {

        // Api接口地址
        String path = getApi(MODULE_PATH,"send");
        // Data
        Map<String,Object> data = new HashMap<>();
        data.put("targetId", message.getTargetId());
        data.put("model",message.getModel());
        data.put("content", message.getContent());
        HttpUtils.sendPost(
                        client.getApiHostType(),
                        path,
                        data,
                        client.getAccessToken(),
                        callback);

    }



服务端代码:
 
@ApiImplicitParams(value = {@ApiImplicitParam(
        name = "access_token",
        required = true,
        dataType = "string",
        paramType = "query",
        value = "访问 Token")})
@RequestMapping(value = "send", method = RequestMethod.POST)
public Map<String,String> send(@Valid @RequestBody SendPrivateMsgParm parm) throws Exception {
 
        for (String targetId : parm.getTargetId())
        {
            // 消息ID
            String messageId = UUIDHelper.getMessageId();
            result.put(targetId,messageId);

            if(messageTemp == MessageTemp.LongTextMessage){

                // 长文本消息 (记录)
                CreateMsgCmd cmd = new CreateMsgCmd(
                        messageId,
                        currentUser().getUserId(),
                        Integer.parseInt(targetId),
                        ProtocalType.C.FROM_CLIENT_TYPE_OF_COMMON$DATA,
                        MessageTypeu.Content,
                        messageTemp,
                        parm.getContent());
                msgTask.create(cmd);
                parm.setContent("长文本消息");
            }

            Body body = new Body(
                        messageId,
                        parm.getContent(),
                        messageTemp);

             LocalSendHelper.sendData(
                     String.valueOf(currentUser().getUserId()),
                     targetId,
                     body.toJsonString(),
                     MessageTypeu.Content,
                     (sucess, extraObj) -> {
                         if(sucess)
                         {
                             
                         }
             });
        } 
     
}

引用:cotide 发表于 2019-09-26 15:24
客户端A是通过http发送给服务端,进行转发到客户端B。客户端B的ACK应答码应该是返回给服务端的吧?
所以 ...

如果你要在服务端知道,收服务端主动发起的消息有没有送达给对方,你可以看下官方Demo里服务端的这个实现类:
WX20190926-165957@2x.png

它的原理,跟客户是一样的,对应的接口是:MessageQoSEventListenerS2C

你研究一下。
签名: 《马蜂窝旅游网的IM客户端架构演进和实践总结》:http://www.52im.net/thread-2796-1-1.html
引用:JackJiang 发表于 2019-09-26 17:02
如果你要在服务端知道,收服务端主动发起的消息有没有送达给对方,你可以看下官方Demo里服务端的这个实现 ...

服务端的MessageQoSEventListenerS2C会反馈Qos的情况,这个阅读代码的时候看到了。好像还没理解我的问题,其实我是想让客户端A知道消息状态。是不是这部分我需要自己去实现?服务端收到Qos, 我再反馈给客户端A?
引用:JackJiang 发表于 2019-09-26 17:02
如果你要在服务端知道,收服务端主动发起的消息有没有送达给对方,你可以看下官方Demo里服务端的这个实现 ...

我现在是用上面示例的代码,只有服务端触发MessageQoSEventListenerS2C的事件,而安卓端没触发。不知道能不能理解我的意思。主要客户端A发送消息UDP有长度限制,所以我用HTTP 把消息给服务端,让它帮我(做长文本的存储,然后发给客户端MessageId,自行拉取)发到客户端B。由于是服务端发给客户端B,所以Qos反馈给服务端的MessageQoSEventListenerS2C的事件,然而客户端A没有Qos反馈信息。
引用:cotide 发表于 2019-09-26 17:26
我现在是用上面示例的代码,只有服务端触发MessageQoSEventListenerS2C的事件,而安卓端没触发。不知道能 ...

客户端A肯定再没法直接知道这条消息的发送状啊,因为长连接消息不是它发出的,要想让它知道,你服务端得单独给他下一条你的自定义指令,这个看你逻辑怎么实现。

不过,看你这功能定义,挺操蛋的,为什么不能直接A通过长连接发送呢
签名: 《马蜂窝旅游网的IM客户端架构演进和实践总结》:http://www.52im.net/thread-2796-1-1.html
引用:JackJiang 发表于 2019-09-26 19:14
客户端A肯定再没法直接知道这条消息的发送状啊,因为长连接消息不是它发出的,要想让它知道,你服务端得 ...


1.其实客户端A登陆的时候,是将长连接信息放在服务端缓存。

2.客户端A发送报文信息给服务端,里面定义了发送人和接收人。因为服务端记录了已经存活的长连接信息,所以只能由服务端发消息吧?

3.服务端会找到接收人的长链接来进行消息推送。

不是我不想在客户端A找到长链接来发,是长链接登陆时候注册在服务端,然而Qos的响应是针对发起的对象的响应。所以客户端A发给服务端,收到Qos事件只能证明,我的消息服务端已经接收了,然后服务端跟客户端B的交互中,如果Qos丢失,我就做为客户端B的离线消息处理

因为客户端A没办法知道客户端B有没收到消息,只知道服务端接收了我的消息。我是这样理解,不知道有没错
引用:cotide 发表于 2019-09-26 21:32
1.其实客户端A登陆的时候,是将长连接信息放在服务端缓存。

2.客户端A发送报文信息给服务端,里面定 ...

你这说的乱七八糟,没看懂。

回根到事情的本质:你直接把你要做的功能,用一句话描述出来,要让煞笔也能理解的方式。别说具体技术细节,煞笔不懂这些
签名: 《马蜂窝旅游网的IM客户端架构演进和实践总结》:http://www.52im.net/thread-2796-1-1.html
引用:JackJiang 发表于 2019-09-26 19:14
客户端A肯定再没法直接知道这条消息的发送状啊,因为长连接消息不是它发出的,要想让它知道,你服务端得 ...

不好意思我把ACK跟Qos混淆了,应该是这样:-
1、客户端A发给消息给服务器S
2、服务器S消息转发给客户端B,如果Qos重发出现问题(促发MessageQoSEventListenerS2C 的messageLost方法这个时候客户端A是不知道客户端B没接收到, 那在messageLost方法中是不是需要将消息存放到客户端B的离线消息中?

  






打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部