Apollo 技术文档Apollo 技术文档
指南
  • 架构概述
  • BigWorld 架构深度解析
  • BigWorld 进程架构与玩家生命周期
  • AOI九宫格系统详解
  • AOI广播与消息去重
  • Base 模块
  • Core 模块
  • Runtime 模块
  • Data 模块
  • Network 模块
  • /modules/actor.html
  • Game 模块
  • BigWorld 模块
服务器应用
API 参考
QA
GitHub
指南
  • 架构概述
  • BigWorld 架构深度解析
  • BigWorld 进程架构与玩家生命周期
  • AOI九宫格系统详解
  • AOI广播与消息去重
  • Base 模块
  • Core 模块
  • Runtime 模块
  • Data 模块
  • Network 模块
  • /modules/actor.html
  • Game 模块
  • BigWorld 模块
服务器应用
API 参考
QA
GitHub
  • MMORPG 架构 QA

Q31: KBEngine 如何高效广播?如何保证消息不重复?

核心结论

这类问题的关键不只是“怎么广播”,还包括“广播接收者集合由谁算”和“多条路径汇合时怎么避免重复下发”。

高效广播通常依赖:

  • AOI 裁剪
  • 观察者集合维护
  • 增量状态同步

避免重复则依赖:

  • 明确单一广播来源
  • 接收者去重
  • 路由边界清晰

一、广播为什么会复杂

场景内广播往往同时涉及:

  • 实体移动
  • AOI 进入离开
  • 邻区镜像
  • 多节点协作

只要实体可能同时被多个逻辑路径观察到,重复通知问题就会出现。

二、广播高效的前提是接收者集合先算对

最重要的一步是知道“谁应该收到这条消息”。

这通常依赖:

  • AOI 观察者集合
  • Witness 或类似观察关系
  • 邻区实体镜像

如果观察者集合本身算得粗,后面再怎么优化发送都只是补救。

三、为什么会出现重复消息

常见原因包括:

  • 同一目标同时通过本地和邻区路径收到更新
  • 实体在边界区域被多次纳入广播集合
  • 创建、更新、销毁事件跨路径重复触发

本质上是“同一观察者对同一实体有多条传播路径”。

四、怎么避免重复

1. 明确单一权威来源

同一实体的权威状态更新应只有一个真实来源,其他路径只能转发,不应重复生成同类事件。

2. 广播前去重观察者集合

无论接收者来自多个邻接集合还是多个子系统,最终下发前都应合并去重。

3. 事件和状态分离

状态同步可按版本覆盖,事件同步则要保证只产生一次。

如果两者混在一起,重复问题会更难排查。

五、真正高效的点通常不在 send,而在数据组织

常见优化方向包括:

  • 维护稳定观察者集合
  • 脏字段同步
  • 批量编码
  • 多连接复用同一消息体

这些通常比单纯抠 socket 层收益更大。

六、边界区域为什么最容易出重复

因为实体可能同时被:

  • 当前分区玩家观察
  • 邻区玩家观察
  • Ghost 镜像链路观察

如果系统没有把“显示给谁”和“由谁下发”分清楚,就会出现重复创建或重复更新。

七、工程上更稳妥的处理方式

常见策略是:

  • 权威实体只在一处生成核心更新
  • 邻区镜像只负责补充观察,不重复产出同类事件
  • 最终到客户端前再做一次目标集合去重
  • 客户端对状态消息再按版本保护

这样服务端和客户端各承担一层防重。

八、常见误区

1. 消息重复一定是客户端问题

很多时候根源其实在服务端多路径广播。

2. 只要客户端去重就够了

不够。服务端重复广播会浪费大量带宽和 CPU。

3. 广播优化就是提高发送速度

真正决定上限的往往是观察者集合维护和重复路径控制。

参考资料

  • KBEngine AOI / Witness 机制相关资料
在 GitHub 上编辑此页
最后更新: 3/20/26, 6:06 AM
贡献者: cuihairu