外观
事件参考
服务端推送在同一 WebSocket 上发送。先按 event_id 去重,再按会话序号、对象版本或删除修订归并。HTTP 写回包若含相同 event_id,与实时回包只应用一次。
消息与会话
| event | data 字段 | 处理方式 |
|---|---|---|
| message.created | previous_updated_at:integer、unread_delta:integer|null、conversation:Conversation、message:Message | 追加新消息,归并摘要与未读 |
| message.recalled | 同 created | 按 mid 更新为撤回状态 |
| message.deleted | previous_deletion_revision:integer、deletion_revision:integer、conversation:Conversation、message:Message | 本人删除 tombstone,消费序号,隐藏内容 |
| conversation.updated | previous_updated_at:integer、unread_delta:integer|null、conversation:Conversation | 归并本人设置、已读、对端已读等状态 |
| conversation.typing | conversation_id:string、user:User、typing:boolean、expires_at:integer | 按租约显示,不持久化 |
Conversation、Message、User 完整字段见公共对象。消息事件不是只含 mid 的通知。撤回/删除后保留 mid、conversation_seq,内容为空属于合法状态。
previous_updated_at 用于发现内容版本缺口;本人设置与对端已读可以不推进共享内容版本。unread_delta 是可空增量,不等同会话绝对 unread_count。共享群事件中的个人 read_seq、unread_count、pinned、muted、group_role、send_forbidden_until、state、announcement_unread、mention_unread 可为 null;保留现有私有状态,再依据消息与本人身份归约,无法确定时用 HTTP 校准。
message.deleted 只投递当前账号全部设备,不影响其他成员,不推进共享会话内容版本。删除修订不连续时仅校准对应消息窗口。
资料、关系、群和申请
| event | data 的完整字段 |
|---|---|
| profile.updated | user:User、relation:object|null |
| relation.updated | conversation_id:string、user:User、relation、conversation_settings、permissions |
| group.updated | group:Group |
| group.members.updated | group:Group、members:GroupMember[]、removed_user_ids:string[] |
| membership.updated | group:Group、membership、permissions |
| notice.updated | unread:{notice:integer}、items:Notice[] |
profile.updated 的 relation 是接收者的展示投影,含 status(friend/stranger)、remark、display_name、initial、updated_at;本人收到自己的更新时为 null。它不等同 relation.updated 里的完整关系,后者还含 blocked。
relation.updated 的 relation、conversation_settings、permissions 与UserProfile一致。membership.updated 包含当前账号成员状态,active / left / removed / dissolved;离群、被移除或解散后及时关闭对应操作入口。
group.members.updated 的 members 为新增或改变后的完整成员,removed_user_ids 是被移除外部 ID;每个事件分片合计 1–499 个变化。Group 和 Membership 分别有自己的版本字段,不要用群公开资料版本覆盖更新的本人设置。
notice.updated 给出绝对 unread.notice 与变更的申请摘要列表。列表为增量,不意味着应清空未出现的申请。
运行配置
configuration.updated 的 data 为:
json
{"revision":2,"capabilities":{"direct_chat":true,"group_chat":true,"add_friend":true,"create_group":true,"voice":true,"emoji":true,"image":true,"video":true,"file":true,"contact_card":true,"read_receipt":true,"typing_indicator":true,"forward":true,"group_qrcode":true,"group_member_add_friend":true,"report_user":true,"stranger_chat":true,"voice_call":true,"video_call":true},"media_limits":{"image":{"max_bytes":8388608},"voice":{"max_bytes":10485760,"max_duration_ms":60000},"video":{"max_bytes":8388608},"file":{"max_bytes":8388608}}}只应用 revision 大于当前配置版本的事件,整体替换能力与媒体限制。/sync.configuration_revision 与此事件的 revision 是同一版本空间;断线后通过 /sync 恢复。
通话
| event | data | 用途 |
|---|---|---|
| call.updated | {call: Call} | 离散通话状态变化 |
| call.pulse | {call: Call} | 振铃期被叫收到的最新租约 |
Call 完整字段见通话响应。两种事件不带 HTTP control,也不带 TRTC 凭证。按 call_id 与 version 归并;同账号多设备根据 self.selected_device_id 收敛,未胜出的设备停止占用来电界面。
输入状态和通话都不进入 /sync,不从聊天历史恢复输入中状态,也不把过期来电通知当作仍可接听的通话。
在线状态
presence / peer_presence 是资料、目录、成员和会话 HTTP 读取中的快照。服务器没有单独的 presence.changed 事件;不要实现对该事件的等待逻辑。presence 使用 online_updated_at,与 profile_updated_at 分开比较。
