阅后即焚


阅后即焚:用户A发送消息,当用户B接收并查看消息后,消息将同时从用户A和用户B的设备上删除。

阅后即焚消息传递过程

用户A发送消息给用户B,当用户B查看消息后,发送已读回执给用户A,并删除掉查看后的消息,用户A收到消息回执,同时删除消息。

  1. 用户A发送消息,消息扩展中添加阅后即焚标识,表示本条消息是阅后即焚消息。
  2. 用户B收到消息,解析消息扩展中是否有阅后即焚的标识,如果有,发送已读回执时删除本地消息。
  3. 用户A收到消息回执,从本地查询该消息回执对应的消息是否是阅后即焚消息,如果是就删除本地消息并更新显示。

发送阅后即焚消息

Android示例

EMMessage message = EMMessage.createSendMessage(EMMessage.Type.TXT);
message.setChatType(ChatType.Chat);//阅后即焚针对单聊
TextMessageBody txtBody = new TextMessageBody("这是一条阅后即焚的消息");
// 设置消息body
message.addBody(txtBody);
// 设置要发给谁,用户username或者群聊groupid
message.setReceipt(toChatUsername);
// 通过扩展字段标识为阅后即焚消息(参数可以自定义,但要求与iOS保持一致)
message.setAttribute("fire","ephemeral");
EMChatManager.getInstance().sendMessage(message,new EMCallBack() {
	@Override
	public void onSuccess() {}			

	@Override
	public void onProgress(int progress, String status) {}
			
	@Override
	public void onError(int code, String error) {}

});

iOS示例

#define FIRE_FLAG @"fire" // 阅后即焚关键字

// 此处以文字消息举例
EMChatText *txt = [[EMChatText alloc] initWithText:@"test"];
EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithChatObject:txt];
EMMessage *msg = [[EMMessage alloc] initWithReceiver:@"toUsername" bodies:@[body]];
msg.messageType = eMessageTypeChat; // 阅后即焚只能是单聊
msg.ext = @{FIRE_FLAG:@YES};
[[EaseMob sharedInstance].chatManager asyncSendMessage:msg progress:nil];

接收阅后即焚消息,查看后发送回执并删除本地消息

Android示例

EMChatManager.getInstance().registerEventListener(new EMEventListener() {
		
	@Override
	public void onEvent(EMNotifierEvent event) {
		switch (event.getEvent()) {
		case EventNewMessage: // 阅后即焚消息
		{
			EMMessage message = (EMMessage) event.getData();
			try {
				String messageFlag = message.getStringAttribute("fire");
			} catch (EaseMobException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			break;
		}
		default:
			break;
		}
	}
}, new EMNotifierEvent.Event[] { EMNotifierEvent.Event.EventNewMessage});
//当接收方收到消息并阅读以后删除消息,同时向发送方发送已读回执	
EMChatManager.getInstance().ackMessageRead(message.getFrom(), message.getMsgId());

iOS示例

// 接受离线消息
- (void)didReceiveOfflineMessages:(NSArray *)offlineMessages{
   	for (EMMessage *msg in offlineMessages) {
        	[self didReceiveMessage:msg];
	}
}

- (void)didReceiveMessage:(EMMessage *)message{
    	// 判断是否有阅后即焚消息标识
	if ([message.ext[FIRE_FLAG] boolValue]) {
    	    //update ui
	}
}
// 当用户已经读取过消息后,删除消息并发送已读回执
- (void)fireMessageAndSendAck:(EMMessage *)message{
    	// 发送已读回执
        [[EaseMob sharedInstance].chatManager sendReadAckForMessage:message];
    	// _conversation ,消息所在会话
	[_conversation removeMessage:message];
    	// 更新显示
}

消息发送方收到回执,判断需要焚毁,删除本地消息

Android示例

EMChatManager.getInstance().registerEventListener(new EMEventListener() {
			
	@Override
	public void onEvent(EMNotifierEvent event) {
		switch (event.getEvent()) {
		case EventReadAck: // 已读回执消息
		{
			EMMessage message = (EMMessage) event.getData();
			try {
				String messageFlag = message.getStringAttribute("fire");
				if(messageFlag != null){//判断如果扩展字段是否有阅后即焚字段,如果有则删除
					EMConversation conversation = EMChatManager.getInstance().getConversation(message.getFrom());
					conversation.removeMessage(msgId);

				}
			} catch (EaseMobException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
					
			break;
		}
		default:
			break;
		}
	}
}, new EMNotifierEvent.Event[] { EMNotifierEvent.Event.EventReadAck});

iOS示例

// 收到已读回执
- (void)didReceiveHasReadResponse:(EMReceipt *)resp{
        EMConversation *conversation = [[EaseMob sharedInstance].chatManager conversationForChatter:resp.conversationChatter conversationType:eConversationTypeChat];
    	EMMessage *message = [conversation loadMessageWithId:resp.chatId];
	// 判断是否是阅后即焚消息
    	if ([message.ext[FIRE_FLAG] boolValue]) {
            // 如果是阅后即焚消息,删除本地并更新UI
	    [conversation removeMessage:message];
    	    // update ui
	}
}

上一页:群组@功能

下一页:消息回撤