通信是分布式系统的核心问题。本项目中的通信需求可以归纳为两个问题:模块之间如何交换信息(引擎间通信);后端如何将运行状态实时推送给前端(前后端通信)。

通信是分布式系统的核心问题。本项目中的通信需求可以归纳为两个问题:

  1. 模块之间如何交换信息(引擎间通信)?
  2. 后端如何将运行状态实时推送给前端(前后端通信)?
通信场景 通信模型 特点
研究进度广播 一对多 实时低延迟
论坛摘要收集 多对一 异步、可缓冲
HOST 发言反馈 一对多、拉取模式 非实时
进度推送到前端 多对多 实时、支持断线重连
错误通知 多对一 实时、消息不可丢失

如果为每一种场景单独写一套通信通道,就要分别实现一对多、多对一、拉取、推送等多套机制,代码会大量重复、架构臃肿,维护成本极高。

EventBus 的核心价值:用一套统一的发布订阅模型,统一承载全部 5 类通信场景

1. 统一抽象,消除多套通信通道

不管是一对多广播、多对一接收,全部统一为:发布者发布事件,订阅者按需订阅事件。

  • 一对多:一个事件发布,多个订阅者接收(进度广播)
  • 多对一:多个模块发布同一事件,只由一个模块订阅(论坛摘要收集)
  • 同一个事件可以同时供给后端内部组件 + SSE 网关,实现多消费方。

2. 适配不同的通信特性

  • 实时流式进度、错误消息:事件即时派发,满足低延迟;
  • 论坛摘要这类异步可缓冲任务:EventBus 支持异步派发,不会阻塞引擎主流程;
  • HOST 发言反馈采用拉取模式:事件发生时先缓存数据(forum_reader),引擎不实时订阅,需要的时候主动读取缓存,不需要事件推送通知。

3. 实现前后端通信与后端内部通信两套线路复用同一总线

后端引擎之间内部交互、需要转发到浏览器 SSE 的事件,全部走同一个 EventBus。SSE Router 仅仅是总线众多订阅者之一,负责把指定事件转换成 SSE 流向浏览器推送;引擎本身完全不感知前端的存在。

4. 模块解耦,降低复杂度

引擎只负责 publish 发布事件,不需要硬编码调用下游模块;新增通信逻辑,只需要新增订阅,不需要修改原有引擎代码。避免模块之间大量直接依赖。

5. 兼容前端 SSE 断线重连的配套能力

事件在总线流转,可以做缓存、回放,配合 SSE 实现前端断线重连之后恢复事件流。

一句话总结

系统内部混合了一对多广播、多对一收集、拉取模式、前后端流式推送等多种通信模式,如果每个场景单独实现通信通道会极度复杂。EventBus 使用统一的发布订阅模型,把所有通信场景收敛到一套机制,同时完成后端模块解耦,分离后端内部事件和向前端推送事件两条链路。