野火聊天室的一些细节
1. 群组和聊天室的对比
在野火IM中,聊天室和群组看起来有些类似,都可以多人收发消息,但二者在设计和使用场景上有本质区别。
| 对比项 | 群组 | 聊天室 |
|---|---|---|
| 成员关系 | 持久化社交关系,加入后长期存在,直到主动退群或被踢出 | 临时状态,进入后可收发消息,离开后不再接收消息,不保留成员关系 |
| 消息存储 | 消息在客户端本地数据库存储 | 消息不在客户端本地存储 |
| 消息推送 | 有推送,离线成员可收到推送通知 | 没有推送,不在聊天室中的用户不会收到消息 |
| 人数限制 | 建议不超过1000人,超级群组不建议超过10万人 | 无限制,可支撑海量观众同时在线 |
| 管理功能 | 丰富,包括群主、管理员、黑名单、白名单、全员禁言、群公告等 | 仅有基本的创建、加入、离开、获取信息、成员信息、禁言、踢人。其他业务自行实现 |
| 消息可靠性 | 消息100%送达,每条消息都会投递给每个群成员 | 当消息堆积过多、压力过大时,会丢弃部分低优先级消息,只保留高优先级消息 |
| 同时存在性 | 用户可加入无数个群组 | 同一时刻只能加入一个聊天室 |
2. 如何选择
2.1. 适合使用群组的场景
- 工作协同:项目团队、部门沟通、任务分配等,成员关系固定,需要长期保留聊天记录供后续查阅。
- 亲友社交:家人群、同学群、兴趣小圈子,成员之间需要双向互动,消息必须确保每个人都能收到。
- 会员/客户运营:VIP 客户群、售后服务群,需要推送通知触达离线用户,且消息需要持久化存储。
- 本地社群:小区业主群、拼车群、二手交易群,成员需要随时翻看历史消息,管理功能(禁言、踢人、公告)使用频繁。
2.2. 适合使用聊天室的场景
- 直播互动:主播与海量观众实时互动,观众流动性大,不需要保留聊天记录,离线观众也不需要被消息打扰。
- 在线课堂/ webinar:老师授课,学生实时提问,课程结束后学生自动离开,不需要课后回看聊天内容。
- 赛事/活动直播:体育比赛、演唱会、发布会等,需要支撑数万甚至数十万人在线围观和弹幕互动。
- 临时话题讨论:热点事件快闪讨论、红包雨活动、抽奖互动等,人员临时聚集,活动结束后自然解散。
- 语音房/派对房:用户进房旁听或上麦交流,离开房间后不再接收房内消息,强调实时性而非持久性。
2.3. 一句话总结
群组适合需要「长期关系 + 消息必达 + 历史可查」的场景;聊天室适合需要「临时聚集 + 海量并发 + 实时互动」的场景。
3. 野火聊天室的配置
IM服务配置文件wildfirechat.conf中聊天室的配置项如下:
## 是否开启聊天室功能,默认开启,当不需要聊天室功能时可以关闭
chatroom.enable true
## 聊天室观众空闲退出时间,单位为毫秒,默认为15分钟,0为永远不退出
chatroom.participant_idle_time 900000
## 聊天室观众离线退出时间,单位为毫秒,默认为1分钟,0为永远不退出
chatroom.participant_inactive_time 60000
## 用户向聊天室发送消息,自动加入聊天室
chatroom.rejoin_when_active true
## 当一个聊天室不存在时,如果有用户加入就自动创建
chatroom.create_when_not_exist true
## 聊天室内高优先级消息类型。当聊天室消息堆积过多时,会抛弃掉部分普通消息,保留高优先级消息。
chatroom.key_message_type_list 1,2,3,4,5,6,7,8
## 当进入聊天室时,自动拉取历史消息数量,默认是20,最大不能超过50。如果需要更多数量,可以调用getRemoteMessage方法。
## 注意拉取消息是拉取内存中的消息,如果服务器重启,内存中消息为空,将会拉不到,必须是重启之后发送的消息才能拉取到。但getRemoteMessage不受影响。
chatroom.pull_message_count_when_join 20
## 一个用户同一时刻只能加入一个聊天室。
## 当一个客户端加入一个聊天室时,如果这个用户的其他端已经加入一个聊天室了,kickoff_other_platform为true时会自动退出之前的聊天室,为false时会返回225的错误码。
## 当自动退出聊天室时,客户端不会收到任何通知,只是不会再收到消息。
chatroom.kickoff_other_platform true
## 聊天室只使用内存消息,不落库。当聊天室热度很高时,可以只使用内存消息。默认为false。运营方需要确认监管的合规性。
chatroom.only_memory_message true
3.1. 配置项说明
- chatroom.enable:控制聊天室功能总开关。
- chatroom.participant_idle_time:空闲退出时间,指用户在聊天室里没有活跃行为超过该时间后,会自动被服务器移出聊天室。这里的活跃行为包括发送消息、主动加入,也包括拉取/接收消息。换句话说,只要聊天室内持续有消息流动,用户就不会被 idle 退出;只有当聊天室在指定时间内完全没有消息时,观众才会因为 idle 被自动退出。默认15分钟。如果业务场景下聊天室可能出现长时间冷场,但又希望观众保持在线,就需要适当调大这个值,或者设为0。
- chatroom.participant_inactive_time:离线退出时间,指用户网络断开后超过该时间未恢复,服务器会将其移出聊天室。默认1分钟。
- chatroom.rejoin_when_active:开启后,用户向聊天室发送消息时会自动加入该聊天室(如果还没加入的话)。
- chatroom.create_when_not_exist:开启后,当用户加入一个不存在的聊天室ID时,服务器会自动创建该聊天室。
- chatroom.key_message_type_list:高优先级消息类型列表。当聊天室消息堆积过多时,服务器会丢弃普通消息以减轻压力,但会保留列表中指定类型的消息。
- chatroom.pull_message_count_when_join:进入聊天室时自动拉取的历史消息条数,默认20,最大50。注意这些消息来自服务器内存,如果服务器刚重启,内存中无消息,可能拉不到历史消息。
- chatroom.kickoff_other_platform:控制用户多设备加入聊天室的互踢策略。
- chatroom.only_memory_message:开启后聊天室消息只保存在内存中,不写入数据库,适合超高并发的直播场景,但服务器重启后历史消息会丢失。
4. 聊天室保活
4.1. 为什么要保活
从上面的配置可以看出,chatroom.participant_idle_time 和 chatroom.participant_inactive_time 都会让服务器自动将用户移出聊天室。如果聊天室内超过指定时间没有消息,就可能被踢出,导致收不到后续消息。因此,对于需要长时间在线的业务(如会议、直播、在线课堂),必须进行保活。
4.2. 保活的正确方式
保活的核心思路是:避免聊天室长时间没有任何消息,从而触发 participant_idle_time 导致观众被踢出。建议采用以下两种方式之一:
方式一:每个用户定时调用加入聊天室接口
在客户端为每个用户启动一个定时器,每隔一定时间(比如3分钟)调用一次 joinChatroom,主动刷新用户的活跃状态。这是最安全、最不会影响聊天室内容的方式。
方式二:使用一个专用账号(如管理员/机器人)定时发送不存储的消息
如果希望简化客户端逻辑,可以由服务端或一个专用账号每隔3分钟向聊天室发送一条不存储的保活消息(如自定义消息,Persist 属性设为不存储)。这样聊天室内始终有消息流动,观众的 idle 计时器会被重置。
注意:千万不要让每个用户都发消息来保活。如果成百上千的用户同时发送保活消息,会导致聊天室消息量爆炸,不仅污染聊天内容,还会给服务器带来巨大压力。
推荐在方式一和方式二中根据业务需求选择:方式一侧重于客户端自主保活,方式二侧重于服务端统一保活。
4.3. 如何不保活
保活总是麻烦的,但在某些场景下,可以不使用保活。如果聊天室的存活时间是短暂有限的,比如会议或者一个课堂,可以把chatroom.participant_idle_time改成一个肯定超过聊天室存活时长的设置,比如设置为1天。因为应该没有会议或者课堂能够连续持续超过1天,这样加入会议的用户就不会在会议中聊天室被踢出。