uniapp 实现腾讯云 IM 消息已读回执

发布于:2025-05-30 ⋅ 阅读:(15) ⋅ 点赞:(0)

uniapp 实现腾讯云 IM 消息已读回执处理全攻略

一、功能实现原理

腾讯云 IM 的已读回执功能通过 消息已读上报机制 实现,核心流程如下:

  1. 接收方阅读消息时,客户端自动上报已读状态
  2. 云端记录最新已读时间戳(精确到会话维度)
  3. 发送方通过监听事件获取接收方的已读状态
  4. 群聊场景支持显示已读成员列表(需开通高级功能)

二、核心实现步骤

1. 发送消息时启用已读回执

// 创建文本消息(启用已读回执)
export function createTextMessageWithReceipt(options) {
  const tim = initIM()
  
  return tim.createTextMessage({
    to: options.to,
    conversationType: options.type || 'C2C',
    payload: { text: options.content },
    cloudCustomData: JSON.stringify({
      needReadReceipt: true // 启用已读回执
    })
  })
}

2. 接收方自动上报已读

// 初始化时配置自动已读
tim = TIM.create({
  SDKAppID: config.SDKAppID
})

// 进入会话时标记消息为已读
export async function markConversationRead(conversationID) {
  const tim = initIM()
  const conv = tim.getConversationProfile(conversationID)
  
  // 获取最后一条消息
  const lastMsg = conv.getLastMessage()
  if (!lastMsg) return
  
  // 上报已读到最新消息
  await tim.messageReportedRead({
    conversationID,
    lastMsgID: lastMsg.clientMsgID
  })
}

3. 监听已读回执通知

// 全局消息监听器
export function setupMessageListener(callback) {
  const tim = initIM()
  
  tim.on(tim.EVENT.MESSAGE_READ_BY_PEER, (event) => {
    const { data } = event
    
    // 更新本地消息状态
    data.forEach(receipt => {
      const conv = tim.getConversationProfile(receipt.conversationID)
      conv.setMessageRead(receipt.messageKey.clientMsgID)
      
      // 触发UI更新
      uni.$emit('message-read', {
        conversationID: receipt.conversationID,
        msgID: receipt.messageKey.clientMsgID,
        reader: receipt.reader
      })
    })
  })
}

4. 群聊已读成员处理

// 获取群聊已读成员列表
export async function getGroupReadMembers(groupID, msg) {
  const tim = initIM()
  
  try {
    const res = await tim.getGroupMessageReadMembersList({
      groupID,
      messageKey: tim.createMessageKey(msg.clientMsgID)
    })
    
    return res.data.readMemberList || []
  } catch (error) {
    console.error('获取已读成员失败:', error)
    return []
  }
}

三、关键问题处理

1. 性能优化策略

// 批量上报已读(防抖处理)
let readReportDebounce = null

export function batchReportRead(conversationID, lastMsgID) {
  clearTimeout(readReportDebounce)
  
  readReportDebounce = setTimeout(async () => {
    try {
      await tim.messageReportedRead({
        conversationID,
        lastMsgID
      })
    } catch (error) {
      console.warn('批量上报失败:', error)
    }
  }, 500) // 500ms防抖
}

2. 隐私保护方案

// 用户隐私设置(示例)
const PRIVACY_CONFIG = {
  DISABLE_READ_RECEIPT: false // 用户是否关闭已读回执
}

// 发送消息时动态判断
export function createMessage(options) {
  const tim = initIM()
  
  return tim.createTextMessage({
    ...,
    cloudCustomData: JSON.stringify({
      needReadReceipt: !PRIVACY_CONFIG.DISABLE_READ_RECEIPT
    })
  })
}

3. 跨平台差异处理

// 微信小程序特殊处理
#ifdef MP-WEIXIN
// 修复小程序页面切换导致的已读上报延迟
Page({
  onHide() {
    const lastMsg = getCurrentPage().data.lastMsg
    if (lastMsg) batchReportRead(lastMsg.conversationID, lastMsg.clientMsgID)
  }
})
#endif

四、高级功能扩展

1. 已读状态可视化

<template>
  <view class="message-item" :class="{ 'is-read': msg.isPeerRead }">
    {{ msg.payload.text }}
    
    <!-- 群聊已读状态 -->
    <view v-if="isGroup && msg.isPeerRead" class="read-status">
      {{ readCount }}人已读
    </view>
  </view>
</template>

<script>
export default {
  props: ['msg', 'isGroup'],
  computed: {
    readCount() {
      return this.msg.readCount || 0
    }
  }
}
</script>

2. 定时同步已读状态

// 定时任务配置(每5分钟同步)
setInterval(async () => {
  const tim = initIM()
  const convList = await tim.getConversationList()
  
  convList.forEach(conv => {
    const lastMsg = conv.getLastMessage()
    if (lastMsg && !lastMsg.isPeerRead) {
      tim.messageReportedRead({
        conversationID: conv.conversationID,
        lastMsgID: lastMsg.clientMsgID
      })
    }
  })
}, 5 * 60 * 1000)

3. 业务逻辑集成

// 客服场景:自动标记为已读
export function autoReadMessages(conversationID) {
  const tim = initIM()
  const conv = tim.getConversationProfile(conversationID)
  
  // 获取未读消息列表
  const unreadMsgs = conv.getUnreadMessageList()
  
  // 批量标记为已读
  unreadMsgs.forEach(msg => {
    conv.setMessageRead(msg.clientMsgID)
  })
}

五、常见问题排查

  1. Q: 已读回执未触发
    A: 检查消息的 cloudCustomData 是否包含 needReadReceipt: true,确认接收方版本 ≥ 2.18.0

  2. Q: 群聊已读人数不准确
    A: 需在控制台开通「群消息已读回执」增值服务,并确保使用最新版 SDK

  3. Q: 已读状态同步延迟
    A: 检查网络状况,已读回执默认使用长轮询,可升级到 WebSocket 连接

  4. Q: 消息漫游后状态丢失
    A: 确保消息漫游策略包含已读状态(需在控制台配置)

六、最佳实践建议

  1. 重要消息(如系统通知)强制启用已读回执
  2. 对长文本消息采用分片上报策略(每10条上报一次)
  3. 结合消息优先级实现差异化已读策略(如@消息优先处理)
  4. 在消息列表展示最近已读时间(使用TIM.TYPES.CONV_LAST_MSG

网站公告

今日签到

点亮在社区的每一天
去签到