群聊与超大群
实现群 Channel、成员协调、群消息、成员变更,以及十万成员负载边界。
本教程先创建一个普通群,再把同一模型扩展到十万成员。业务系统始终拥有群资料、成员角色、邀请审批、禁言、内容治理和成员数据库;WuKongIM 保存发送权限与投递需要的频道成员,以及频道内有序的消息历史。
1. 创建群 Channel
选择稳定且不可复用的业务群 ID,例如 team-42。在受信服务网络中创建 Channel,并用一个小的初始成员集完成验证:
curl -sS http://127.0.0.1:5001/channel \
-H 'Content-Type: application/json' \
-d '{
"channel_id":"team-42",
"channel_type":2,
"reset":1,
"subscribers":["alice","bob","carol"]
}'成功兼容响应是 {"status":200}。channel_type=2 表示群组 Channel。不要用这个成员列表替代业务群数据库;服务端使用它检查发送权限、同步消息并确定接收人。
成员接口是受信控制面
当前产品 HTTP 路由没有通用业务鉴权。终端用户应先调用你的业务 API,由业务服务验证群角色和审批规则,再执行 WuKongIM 成员变更。
2. 协调成员变化
新增成员:
curl -sS http://127.0.0.1:5001/channel/subscriber_add \
-H 'Content-Type: application/json' \
-d '{"channel_id":"team-42","channel_type":2,"subscribers":["dave","erin"]}'移除成员使用 /channel/subscriber_remove 和相同请求结构。成员变更会去重,并更新每个用户的频道关系。业务服务仍需保存期望成员列表、版本和操作记录,失败后根据已成功的进度继续核对与补偿。
单次请求也可能部分完成
/channel 与带 reset=1 的 subscriber add 会依次执行元数据写入、清空旧成员、分批加入和 large 刷新;名单 set 也会先清空再添加。这些阶段不是事务。超时或错误后应以业务成员快照为期望状态重放,而不是假定本次请求完全没有生效。
Product HTTP 没有普通订阅者、拒绝列表和临时订阅者的对称读接口。需要严格核对时,使用已鉴权的 Manager GET /manager/channels/:channel_type/:channel_id/subscribers 有界分页查询;允许列表虽可由 Product HTTP 读取,但旧接口会一次返回完整列表,不适合大群巡检。
3. 发送并验证群消息
发送者必须满足当前群权限与成员策略。客户端 SDK 使用 channel_id=team-42、channel_type=2;受信服务端示例:
本例使用 SDK 内置文本格式,与 Web 示例一致。编码前的 JSON 是:
{"type":1,"content":"hello team"}下方 payload 是该 JSON 的 UTF-8 Base64。自定义字段和类型需要配套客户端消息解码器,见自定义消息。
curl -sS http://127.0.0.1:5001/message/send \
-H 'Content-Type: application/json' \
-d '{
"from_uid":"alice",
"channel_id":"team-42",
"channel_type":2,
"client_msg_no":"team-42-0001",
"payload":"eyJ0eXBlIjoxLCJjb250ZW50IjoiaGVsbG8gdGVhbSJ9"
}'reason=1 表示这个 Channel 的消息已完成持久提交。它不表示所有成员都在线、所有在线 Session 都写入成功,或者每位用户都已完成 会话目录同步。
Bob 可以同步群日志:
curl -sS http://127.0.0.1:5001/channel/messagesync \
-H 'Content-Type: application/json' \
-d '{
"login_uid":"bob",
"channel_id":"team-42",
"channel_type":2,
"start_message_seq":0,
"limit":20,
"pull_mode":1
}'群内 message_seq 定义唯一顺序。成员的在线投递、RECVACK、未读数和重连恢复仍是不同观测。
4. 验证离群边界
业务系统先提交自己的成员状态,再通过受信调用移除订阅者,并记录可重试任务。成员移除决定之后的发送权限和投递计划,但不会删除既有 Channel 日志,也不会自动清理业务数据库、客户端缓存或历史会话展示策略。
明确产品策略:离群用户能看到哪个历史 sequence、是否删除本地记录、再次入群从哪里同步。这些产品规则不能从“成员行已经删除”自动推导。
扩展到十万成员
不要把十万 UID 放入一次 /channel 或 subscriber_add JSON 请求。推荐使用业务侧协调器:
- 使用几百到约一千 UID 的有界应用批次,并按实际请求大小、延迟和错误率调节;不要把内部 chunk 默认值当作永久 API 上限。
- 每个请求内部仍会分块和去重,但请求内部各阶段以及跨多个 HTTP 请求都不是一个全局事务。失败时保留已成功进度,再通过期望/实际差异修复。
channel.large_group_subscriber_threshold默认是500;普通成员变更后,成员数大于阈值会刷新 large-group 标记。改变阈值后,要通过受控成员协调和验证确认现有 Channel 状态。- 大群消息提交后,服务端分批读取成员并查询在线设备,再按目标节点投递;频道消息历史仍只保留一条消息,不会为十万成员各写一份独立日志。
- SENDACK 确认消息已持久提交,不等待所有接收设备完成投递。需要业务“全部处理”语义时,另建业务回执与聚合流程。
容量验证
上线前至少分别测量:
- 热点群的发送速率、持久提交耗时与 P99;
- 分批查询成员、查找在线设备的耗时,以及提交后投递队列的积压;
- 各节点向客户端写入的耗时、断线比例与重连恢复;
- 成员变更吞吐、部分失败后的进度保存与恢复;
- CPU、内存、磁盘、网络、队列深度、拒绝和端到端尾延迟。
不要只用平均 QPS 推导十万成员容量。继续阅读Channel 核心概念、集群配置和性能测试工具。