消息概览
了解 MessageItem 的创建、发送、接收、查询和状态同步边界。
WASM SDK 使用 MessageItem 表示一条消息。发送消息分为两个阶段:先根据内容创建待发送对象,再把该对象发送到单聊用户或群组。创建方法不会发送消息;发送方法的 Promise 成功也不代表其他客户端已经收到消息。
接收新消息、读取历史、搜索和管理消息都以会话为范围。消息列表应同时保留 conversationID 和 clientMsgID,前者确定所属会话,后者用于定位和合并具体消息。
消息处理流程
| 阶段 | 主要操作 | 说明 |
|---|---|---|
| 创建 | 调用对应的 create*Message() 方法 | 返回待发送的 MessageItem,不会写入服务端或触发新消息事件。 |
| 发送 | 调用 sendMessage() 或 sendMessageNotOss() | 单聊填写 recvID,群聊填写 groupID;另一个目标字段传空字符串。 |
| 接收 | 监听新消息事件 | 根据消息路由字段确定目标会话,再按 clientMsgID 幂等合并。 |
| 查询 | 读取历史、搜索或按 ID 定位消息 | 查询返回调用时的快照,不触发新消息事件。 |
| 更新 | 删除、撤回、修改、置顶或上报已读状态 | 分别处理 Promise 结果、相关事件和必要的重新查询。 |
从浏览器 File 创建的图片、音频、视频和文件消息,通过 sendMessage() 进入 SDK 内置上传与发送流程。媒体资源已经由业务上传服务取得 URL 时,先使用对应的 create*MessageByURL() 创建消息,再通过 sendMessageNotOss() 发送,避免重复上传。
MessageItem 返回结构
创建、发送、接收和查询消息时,data 中的消息对象都是 MessageItem。常用公共字段如下:
| 字段 | 类型 | 说明 |
|---|---|---|
clientMsgID | string | 消息的客户端稳定 ID,用于列表去重、状态更新、查询和历史分页游标。 |
serverMsgID | string | 服务端消息 ID;待发送或发送失败的消息可能尚未取得有效值。 |
sessionType | SessionType | 消息所属的会话类型,例如单聊或群聊。 |
sendID | string | 发送者用户 ID。 |
recvID | string | 单聊接收方用户 ID;群聊消息通常为空。 |
groupID | string | 群聊对应的群组 ID;单聊消息通常为空。 |
contentType | MessageType | 消息内容类型,决定应读取哪个内容字段。 |
createTime | number | 消息对象创建时间。 |
sendTime | number | 消息发送时间,用于消息排序。 |
seq | number | 服务端消息序号;未发送成功的消息可能没有可用序号。 |
senderPlatformID | Platform | 发送消息的客户端平台。 |
senderNickname | string | 发送者昵称快照。 |
senderFaceUrl | string | 发送者头像快照。 |
status | MessageStatus | 当前发送状态:发送中、成功或失败。 |
isRead | boolean | 当前消息的已读状态快照。 |
offlinePush | OfflinePush(可选) | 发送时使用的离线推送配置。 |
ex | string(可选) | 随消息同步的扩展字符串。 |
localEx | string(可选) | 只保存在当前设备本地的扩展字符串。 |
消息正文位于与 contentType 对应的内容字段中,不要通过数组位置或展示文本判断消息类型:
| 消息内容 | 对应字段 |
|---|---|
| 文本、Markdown | textElem、markdownTextElem |
| 图片、音频、视频、文件 | pictureElem、soundElem、videoElem、fileElem |
| @ 消息、回复消息 | atTextElem、quoteElem |
| 转发合并、自定义消息 | mergeElem、customElem |
| 名片、位置、表情 | cardElem、locationElem、faceElem |
| 高级文本、输入状态 | advancedTextElem、typingElem |
| 通知及附加状态 | notificationElem、attachedInfoElem |
conversationID 用于确定消息所属会话,但不是 MessageItem 字段。它来自当前会话、历史查询条件、搜索结果或事件上下文;消息状态通常按 conversationID:clientMsgID 合并。
创建不同内容的消息
| 内容 | 入口 | 注意事项 |
|---|---|---|
| 文本与 Markdown | 创建文本消息、创建 Markdown 消息 | Markdown 内容需要由接收端安全渲染。 |
| 群聊 @ 消息 | 创建 @ 消息 | 只能发送到群聊;会话中的 @ 提醒状态由会话数据维护。 |
| 图片、音频、视频和文件 | 使用文件创建图片消息、使用 URL 创建图片消息 | 其他媒体类型采用相同的“本地文件”或“已上传 URL”路径。 |
| 名片、位置与表情 | 创建名片消息、创建位置消息、创建表情消息 | 创建时保存内容快照,不会随来源资料自动更新。 |
| 回复、转发与合并 | 创建回复消息、创建转发消息、创建合并消息 | 创建结果仍需显式发送。 |
| 自定义业务内容 | 创建自定义消息 | 适合承载需要同步给会话成员的结构化业务数据。 |
只影响当前客户端展示的状态应写入 localEx,不要放入需要同步给其他用户的业务内容。相关说明见设置消息本地扩展。
按任务查找页面
| 任务 | 页面 |
|---|---|
| 发送普通消息或已上传的媒体消息 | 发送消息、发送已上传的媒体消息 |
| 接收在线、离线和仅在线消息 | 接收消息 |
| 加载历史、反向加载或读取消息上下文 | 加载历史消息、反向加载历史消息、读取消息上下文 |
| 按 ID 定位或搜索本地消息 | 按 ID 查找消息、搜索消息 |
| 删除、撤回、修改或置顶消息 | 批量删除消息、撤回消息、修改消息、置顶或取消置顶消息 |
| 清理会话未读数或处理群聊成员级已读 | 标记会话已读、上报群消息已读、查询群消息已读成员 |
| 上报输入状态或识别音频文字 | 上报输入状态、识别音频文字 |
| 插入、删除或扩展仅当前设备可见的消息 | 插入本地单聊消息、删除本地消息、设置消息本地扩展 |
状态同步边界
消息事件的完整监听代码只保留在对应的归属页面:
| 变化 | 事件归属页面 | 合并方式 |
|---|---|---|
| 新消息、离线消息和仅在线消息 | 接收消息 | 确定目标会话后按 clientMsgID 合并。 |
| 消息删除 | 批量删除消息 | 按目标会话和 clientMsgID 移除。 |
| 消息撤回 | 撤回消息 | 按 clientMsgID 更新为撤回状态。 |
| 消息修改 | 修改消息 | 按 clientMsgID 替换消息内容。 |
| 消息置顶 | 置顶或取消置顶消息 | 按 conversationID 更新置顶集合。 |
| 群聊已读回执 | 上报群消息已读 | 按 conversationID 和 clientMsgID 合并。 |
| 输入状态 | 上报输入状态 | 按 conversationID:userID 更新状态。 |
会话未读数、总未读数和群聊 @ 提醒属于会话状态,分别由标记会话已读、维护总未读数和获取会话列表中的事件处理器维护。
创建消息对象和纯查询操作只使用 Promise 返回值建立快照,不会触发共享消息事件。会改变状态的操作应分别处理 Promise 成功、事件到达和重新查询校准,不能将三个阶段视为同一结果。
这个页面有帮助吗?