引用:JackJiang 发表于 2019-09-26 19:14 不好意思我把ACK跟Qos混淆了,应该是这样:- 1、客户端A发给消息给服务器S 2、服务器S消息转发给客户端B,如果Qos重发出现问题(促发MessageQoSEventListenerS2C 的messageLost方法)这个时候客户端A是不知道客户端B没接收到, 那在messageLost方法中是不是需要将消息存放到客户端B的离线消息中? |
引用:cotide 发表于 2019-09-26 21:32 你这说的乱七八糟,没看懂。 回根到事情的本质:你直接把你要做的功能,用一句话描述出来,要让煞笔也能理解的方式。别说具体技术细节,煞笔不懂这些 |
引用:JackJiang 发表于 2019-09-26 19:14 1.其实客户端A登陆的时候,是将长连接信息放在服务端缓存。 2.客户端A发送报文信息给服务端,里面定义了发送人和接收人。因为服务端记录了已经存活的长连接信息,所以只能由服务端发消息吧? 3.服务端会找到接收人的长链接来进行消息推送。 不是我不想在客户端A找到长链接来发,是长链接登陆时候注册在服务端,然而Qos的响应是针对发起的对象的响应。所以客户端A发给服务端,收到Qos事件只能证明,我的消息服务端已经接收了,然后服务端跟客户端B的交互中,如果Qos丢失,我就做为客户端B的离线消息处理 因为客户端A没办法知道客户端B有没收到消息,只知道服务端接收了我的消息。我是这样理解,不知道有没错 |
引用:cotide 发表于 2019-09-26 17:26 客户端A肯定再没法直接知道这条消息的发送状啊,因为长连接消息不是它发出的,要想让它知道,你服务端得单独给他下一条你的自定义指令,这个看你逻辑怎么实现。 不过,看你这功能定义,挺操蛋的,为什么不能直接A通过长连接发送呢 |
引用:JackJiang 发表于 2019-09-26 17:02 我现在是用上面示例的代码,只有服务端触发MessageQoSEventListenerS2C的事件,而安卓端没触发。不知道能不能理解我的意思。主要客户端A发送消息UDP有长度限制,所以我用HTTP 把消息给服务端,让它帮我(做长文本的存储,然后发给客户端MessageId,自行拉取)发到客户端B。由于是服务端发给客户端B,所以Qos反馈给服务端的MessageQoSEventListenerS2C的事件,然而客户端A没有Qos反馈信息。 |
引用:JackJiang 发表于 2019-09-26 17:02 服务端的MessageQoSEventListenerS2C会反馈Qos的情况,这个阅读代码的时候看到了。好像还没理解我的问题,其实我是想让客户端A知道消息状态。是不是这部分我需要自己去实现?服务端收到Qos, 我再反馈给客户端A? |
引用:cotide 发表于 2019-09-26 15:24 如果你要在服务端知道,收服务端主动发起的消息有没有送达给对方,你可以看下官方Demo里服务端的这个实现类: ![]() 它的原理,跟客户是一样的,对应的接口是:MessageQoSEventListenerS2C 你研究一下。 |
引用:JackJiang 发表于 2019-09-26 15:15 客户端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 14:42 你客户端A是通过http发送给客户端B?这是怎么玩出来的? 把客户A的发送代码、服务端的代发代码,贴出来,我看看你是怎么玩的 |
客户端(A)通过http发送消息让服务端去进行消息转发给客户端(B),如果这种情况MessageQoSEvent 应该是在服务端触发的,对于客户端(A)好像收不到任何消息关于Qos的反馈信息。 --------------- 所以这里是不是服务端收到Qos反馈信息,需要给客户端A一些消息状态的信息,这里不是太懂该如何处理? |
引用:JackJiang 发表于 2019-09-26 14:31 客户端(A)通过http发送消息让服务端去进行消息转发给客户端(B),如果这种情况MessageQoSEvent 应该是在服务端触发的,对于客户端(A)好像收不到任何消息关于Qos的反馈信息。 --------------- 所以这里是不是服务端收到Qos反馈信息,需要给客户端A一些消息状态的信息,这里不是太懂该如何处理? |
引用:JackJiang 发表于 2019-09-26 14:31 我也看到MessageQoSEvent这个事件,但客户端A是通过http发送报文让服务端转发,这种情况。所以MessageQoSEvent的事件应该只在服务端触发吧? 这种情况客户端A没办法触发MessageQoSEvent |
引用:cotide 发表于 2019-09-26 12:36 这个在MobileIMSDK是现成的,已经实现了完整的逻辑。 对于A端来说,收到了B端对于这条消息的ACK应答,就表示对方肯定收到了,这是最严谨和有效的方法。 你去看一下Android端的官方Demo里,MessageQoSEvent 这个接口的实现类,对方收到的消息,和超时重传后还无法送达的消息,都会通过这个接口的实现类告诉你,你就可以在这个类里去实现关闭你的转动的菊花(表示消息已送达),或者显示一红色小图标(表示消息未送达) |
引用:JackJiang 发表于 2019-09-26 12:28 我想用于标识消息已经发送出去并对方成功接收(消息已被客户端B接收)。 ## 场景 1. 客户端A发出消息,APP显示转圈圈状态,如果我知道消息已经被B端消费,我就去除转圈状态否则显示红色标识说明消息未能发出。 |
一句话描述一下:你这是打算为用户实现什么功能? |