概述
在 IEC 61850 标准中,报告控制块(Report Control Block, RCB)是用于管理事件报告的核心组件。根据是否使用缓冲区,RCB 分为两种类型:
- URCB(Unbuffered Report Control Block):非缓冲报告控制块
- BRCB(Buffered Report Control Block):缓冲报告控制块
一、URCB(非缓冲报告控制块)
1.1 原理含义
URCB全称Unbuffered Report Control Block 无缓存报告控制块,是一种实时推送模式的报告机制。当数据发生变化时,服务端立即将报告发送给订阅的客户端。核心定位是无事件缓存、实时即时上送、不支持断链补发,主要用于实时性优先、允许少量数据丢包、无需历史事件回溯的常规遥测、实时状态刷新业务场景。
核心特点:
- 报告生成后立即发送,实时性高。摒弃缓存聚合、时序排序、缓存存储等流程,事件触发后直接打包推送,传输延迟极低,可满足电力系统高频遥测刷新、实时状态同步的低延时需求。报文结构更精简,报文收发效率更高,不会出现缓存堆积导致的延迟卡顿问题。
- 不保存历史报告。服务器不开辟专用事件缓冲区,数据集触发的各类更新事件无存储能力,事件生成后仅单次尝试报文封装发送,发送失败、网络断链、客户端离线时,事件会直接丢弃,无法留存历史数据,不做任何历史数据补偿。全程无事件序号记录、无历史数据留存,仅保障当前时刻的实时数据传输。
- 采用独占锁定机制,同一时间只能有一个客户端订阅(针对一个实例),单个报告控制块也是支持多个实例的。URCB无严格的独占绑定限制,相较于BRCB单客户端独占的机制,部分设备模型支持多个客户端同时订阅同一组URCB报告,适配多主站、多后台同时实时监听设备数据的场景,适配性更广。客户端断链、重连后可直接重新使能订阅,无需历史点位同步。
1.2 工作机制
阶段1:配置与客户端订阅初始化
SCL模型预定义URCB,绑定对应数据集DataSet,仅配置基础触发条件:dchg数据变化、qchg品质变化、dupd数据更新、integrity周期完整性报告,无缓存相关配置;
客户端发起简单订阅配置:仅需设置
Enable=true开启报告服务,无需配置EntryID、缓存时长、聚合时间等参数;客户端完成订阅绑定,设备开启实时事件监测与上送逻辑。
阶段2:事件检测与即时封装(核心差异点)
设备后台实时扫描数据集成员,监测四类触发条件,一旦检测到数据变位、品质变化、数据刷新或周期上报触发条件,立即生成对应事件报文;
无缓存入库、无聚合等待:不存储事件、不等待bufTime窗口,触发即封装,单事件对应单报文或即时批量打包;
网络正常、客户端在线时,立即推送报文;网络断链、客户端离线时,当前事件直接丢弃,无任何留存操作。
阶段3:在线实时上送流程
事件触发后即刻完成报文组装,携带实时数据值、数据品质、时标、seqNum序列号等基础信息(无EntryID、无溢出标志);
通过MMS服务实时主动推送至客户端;
报文发送完成后,设备立即清空当前事件数据,不做任何留存,无后续补发、重传逻辑;
支持GI总召唤:客户端下发总召唤指令后,URCB上送数据集当前全量实时数据,总召唤完成后无数据缓存留存。
阶段4:断链与重连处理机制
通信断链、客户端离线期间:所有触发的变位、刷新、品质变化事件全部直接丢弃,设备不做任何记录;
链路恢复、客户端重新使能URCB后:无历史事件补发流程,仅从重连成功的时刻开始,正常上送新产生的事件;
重连后数据断层,断链期间的所有历史数据、变位记录完全丢失,无法回溯。
阶段5:资源管理机制
无缓存溢出问题:因无事件存储区域,不存在缓存占满、数据覆盖、溢出丢失的情况;
无手动/自动缓存清理操作:无需超时清理、无需客户端点位重置,全程零缓存维护开销;
设备重启无缓存清空操作:本身无数据存储,重启后仅需重新订阅即可恢复实时上送。
1.3 实现机制
1.3.1 数据变化监听
当 URCB 启用时,会注册到数据属性的变化监听器列表:
// Urcb.enable() - 注册数据变化监听for(FcModelNodedataSetMember:dataSet){for(BasicDataAttributebda:dataSetMember.getBasicDataAttributes()){if(bda.dchg&&getTrgOps().isDataChange()){synchronized(bda.chgRcbs){bda.chgRcbs.add(this);// 注册到变化监听器列表}}}}代码位置:Urcb.java
1.3.2 报告生成与发送
当数据发生变化时,ServerSap会遍历所有注册的 URCB 并触发报告:
// ServerSap.dataSetMemberChanged() - 数据变化触发报告for(Urcburcb:bdaMirror.chgRcbs){urcb.report(bdaMirror,true,false,false);// 直接发送报告}代码位置:ServerSap.java
1.3.3 独占锁定机制
URCB 采用严格的独占锁定:
独占指的是一个 URCB 实例(instance)只能被一个客户端使能(RptEna=true)。其他客户端如果需要订阅同一个数据集的报告,需要使用另一个 URCB 实例。
// ServerAssociation - URCB 写入处理if(urcb.reserved==null){urcb.reserved=this;// 第一个客户端获得锁定urcb.enable();rsvdURCBs.add(urcb);}elseif(urcb.reserved==this){// 同一客户端再次操作}else{writeResponse.setFailure(newDataAccessError(3L));// 其他客户端被拒绝}代码位置:ServerAssociation.java
1.4 工作流程
客户端设置 RptEna=true ↓ URCB 启用并注册到数据变化监听器 ↓ 数据发生变化 ↓ ServerSap 触发 URCB.report() ↓ 生成 MMS InformationReport PDU ↓ 直接发送给客户端二、BRCB(缓冲报告控制块)
2.1 原理含义
BRCB 全称Buffered Report Control Block 缓存报告控制块,是一种按需读取模式的报告机制。当数据发生变化时,报告先写入缓冲区,等待客户端主动读取。核心定位是带事件缓存、断链恢复补发、支持 SOE 事件顺序记录,用于保护、测控等不能丢失变位、告警、测量事件的业务场景。
核心特点:
- 服务器开辟专用缓冲区,dchg 数据变化、qchg 品质变化、dupd 数据更新、周期完整性报告 integrity四类触发事件全部存入缓存,分配唯一递增
EntryID事件序号,按发生时序排队存储。不立即发送 - 支持历史数据查询。通信断链、客户端离线、网络拥塞时,事件不会丢弃;链路恢复、客户端重新使能 BRCB 后,自动按时间顺序补发全部缓存事件,保障事件不丢失。。
- 写入独占,读取共享。单个 BRCB 同一时刻仅允许一个客户端占用(Owner 属性记录客户端 IP),多客户端需配置多块独立 BRCB;客户端注销、断开后自动释放占用权。
- 允许多个客户端同时读取
专属缓存管理参数(BRCB 独有)
bufTime 缓存聚合时间
事件触发后不立即上送,等待 bufTime 毫秒窗口,窗口内多组变化合并为单条报告报文,减少网络报文风暴;仅 BRCB 支持该参数,URCB 无聚合缓存机制。
bufOvfl 缓冲区溢出标志
缓存容量有限,事件超出缓冲区上限时置位 bufOvfl,通知客户端有历史事件丢失;溢出采用先进先出 FIFO,删除最旧事件存入新事件。
EntryID 事件唯一序列号
每条缓存事件绑定全局递增 EntryID,客户端可指定起始 EntryID,按需拉取某一段历史事件,实现断点续传、历史回溯。
ResvTms 缓存保留时长
超过保留时间的历史事件自动清理,防止缓存无限占用内存。
可靠传输与时序保障
- 报告携带
seqNum主序列号、subSeqNum子序列号,补发时严格按事件原始时序发送,保证 SOE 事件顺序不颠倒,满足故障录波、事故追忆需求。 - 支持GI 总召唤:客户端下发总召唤指令,BRCB 把数据集当前所有实时值打包上送;总召唤报文仅缓存最新一条,新 GI 到来自动覆盖旧 GI,避免缓存塞满大量全量数据。
注意:BRCB 是内存级缓存,设备重启缓存清空;LCB 日志控制块为掉电持久存储,二者应用场景分离:BRCB 用于实时变位补发,LCB 用于长期历史存储。两者的缓存类型需要区分开
2.2 工作机制
阶段 1:配置与客户端订阅初始化
- SCL 模型预定义 BRCB,绑定指定数据集 DataSet,配置触发条件 (dchg/qchg/dupd/integrity)、bufTime、缓存最大条数、ResvTms。
- 客户端发起写操作:
- 设置
Enable=true开启报告; - 写入
EntryID指定补发起始位置(填 0 代表从缓存最早事件开始补发); - 占用 BRCB(Owner 写入客户端地址),完成订阅绑定。
- 设置
阶段 2:事件检测 + 缓存入库(正常在线 / 断链均执行)
后台周期扫描数据集成员,监测四类触发条件:
- dchg:开关位置、保护动作等状态变位;
- qchg:遥测品质失效、检修置位;
- dupd:周期刷新测量值;
- integrity:周期完整性总报,定时上送全量数据。
触发事件生成事件条目,分配递增 EntryID,存入环形缓冲区;
若短时间连续多事件,等待 bufTime 聚合窗口,合并多条事件到同一报告报文,减少报文数量。
链路断开时,入库流程完全不受影响,持续缓存新事件直至缓冲区上限。
阶段 3:在线实时上送流程
bufTime 超时 / 缓存达到单条报文最大容量,组装报告报文;
携带:EntryID、seqNum、事件时标、数据集变化数据、品质、bufOvfl 溢出标志;
通过 MMS 服务主动推送客户端;
客户端接收正常后,不立即删除缓存条目,条目保留在缓冲区,支持重复拉取、断点重传。
阶段 4:断链恢复补发核心流程(BRCB 独有逻辑)
TCP/MMS 链路重建,客户端重新使能 BRCB 并指定起始 EntryID;
服务器检索缓冲区中 EntryID≥客户端指定值的全部历史事件;
严格按事件发生时序(EntryID 从小到大)逐条补发报告,序列号连续递增;
补发完成后,切换为实时推送模式,新事件正常上送;
补发全程 bufOvfl 若置 1,客户端可判断存在丢失历史事件。
阶段 5:缓存清理与溢出处理
FIFO 溢出清理:缓存满时删除最旧 EntryID 条目,写入新事件,置位 bufOvfl;
超时自动清理:事件存储超过 ResvTms,后台定时删除过期条目;
客户端主动清理:客户端可通过写服务重置 EntryID,丢弃指定之前的历史缓存;
设备重启清空:BRCB 为内存缓存,IED 上电后缓存全部清零,无持久化。
2.3 实现机制
2.3.1 缓冲区数据结构
// Brcb.java - 缓冲区实现privatefinalConcurrentLinkedDeque<BufferedReportEntry>buffer=newConcurrentLinkedDeque<>();privatestaticlongentryIdCounter=0;// 递增的条目ID2.3.2 报告写入缓冲区
// Brcb.writeReportToBuffer() - 写入缓冲区publicsynchronizedvoidwriteReportToBuffer(booleanintegrity,booleangi){longentryId=++entryIdCounter;byte[]encodedReport=generateMmsReportPdu(integrity,gi,entryId,timestamp);BufferedReportEntryentry=newBufferedReportEntry(encodedReport,entryId,timestamp);while(buffer.size()>=maxBufferSize){buffer.pollFirst();// 溢出时移除最旧条目bufOvfl=true;}buffer.addLast(entry);}2.3.3 客户端读取缓冲区
// Brcb.getBufferedReports() - 客户端读取publicsynchronizedList<BufferedReportEntry>getBufferedReports(longstartingEntryId,intmaxEntries){List<BufferedReportEntry>entriesToSend=newArrayList<>();for(BufferedReportEntryentry:buffer){if(entry.entryId>startingEntryId){entriesToSend.add(entry);if(entriesToSend.size()>=maxEntries)break;}}returnentriesToSend;}2.3.4 写入独占,读取共享
// ServerAssociation - BRCB 启用检查(写入独占)if(brcb.getReserved()==null){brcb.enable(this);// 只有第一个客户端可以启用}elseif(brcb.getReserved()!=this){writeResponse.setFailure(newDataAccessError(3L));// 其他客户端被拒绝}// BRCB 读取无需检查(读取共享)// getBufferedReports() 没有权限检查,任何客户端都可以调用2.4 工作流程
客户端设置 RptEna=true(获得写入权限) ↓ BRCB 启用并注册到数据变化监听器 ↓ 数据发生变化 ↓ ServerSap 触发 BRCB.writeReportToBuffer() ↓ 报告写入缓冲区,分配 EntryID ↓ 等待客户端主动读取(任何客户端都可以读取) ↓ 客户端调用 getBufferedReports() 获取报告三、URCB 与 BRCB 对比
3.1 核心特性对比
| 特性 | URCB | BRCB |
|---|---|---|
| 传输模式 | Push(推送) | Pull(拉取) |
| 实时性 | 高(实时推送) | 中等(按需读取) |
| 缓冲区 | 无 | 有(ConcurrentLinkedDeque) |
| 历史数据 | 不保存 | 可保存历史报告 |
| 锁定机制 | 完全独占 | 写入独占,读取共享 |
| 多客户端 | 不支持 | 支持(多个读取者) |
| EntryID | 不支持 | 支持(8字节递增) |
| BufOvfl | 不支持 | 支持(缓冲区溢出标志) |
| PurgeBuf | 不支持 | 支持(清空缓冲区) |
| 网络开销 | 持续推送 | 按需读取 |
3.2 访问权限对比
| 操作 | URCB | BRCB |
|---|---|---|
设置RptEna=true | 独占 | 独占 |
设置Resv=true | 独占 | 独占 |
修改DatSet | 独占 | 独占 |
触发GI | 独占 | 独占 |
执行PurgeBuf | 不支持 | 独占 |
| 读取报告 | 独占(只有订阅者) | 共享(任何客户端) |
3.3 适用场景对比
| 场景 | URCB | BRCB |
|---|---|---|
| 实时监控告警 | ✅ 推荐 | ❌ 不适合 |
| 历史数据查询 | ❌ 不支持 | ✅ 推荐 |
| 故障分析 | ❌ 不支持 | ✅ 推荐 |
| 控制操作反馈 | ✅ 推荐 | ❌ 不适合 |
| 低带宽场景 | ❌ 开销大 | ✅ 推荐 |
| 多客户端访问 | ❌ 不支持 | ✅ 支持 |
BRCB 典型应用场景
- 保护装置 SOE 事件上送:断路器变位、保护跳闸、告警,断链恢复后完整补发事故时序;
- 间隔层测控遥信遥测:防止网络瞬时闪断丢失变位信号;
- 远动通信子站:主站短暂离线后,一次性补全间隔全部变位历史;
- 故障追忆、事故分析,对事件完整性、时序有强要求的场景。
URCB 典型应用场景
高频实时遥测数据上送:电压、电流、功率、温度等周期性刷新测量量,允许瞬时丢包,重点保障实时性;
常规设备状态实时刷新:非关键类遥信状态、设备运行常态信号,无需事故追忆与时序记录;
高频刷新、低延时优先的监控场景:后台实时画面刷新、设备常态监测,对历史事件完整性无要求;
多客户端并行监听场景:多后台、多监控终端同时订阅同一设备实时数据的业务场景。
四、设计模式分析
4.1 URCB:观察者模式
URCB 采用经典的观察者模式:
Subject(被观察对象): BasicDataAttribute Observer(观察者): Urcb 通知机制: chgRcbs 列表当数据变化时,所有注册的 URCB 都会收到通知并立即发送报告。
4.2 BRCB:生产者-消费者模式
BRCB 采用生产者-消费者模式:
Producer(生产者): Owner 客户端(写入) Buffer(缓冲区): ConcurrentLinkedDeque Consumer(消费者): 任意客户端(读取) ┌────────────────────────────────────────────────────────────┐ │ BRCB 缓冲区 │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Entry 1 │ Entry 2 │ Entry 3 │ ... │ Entry N │ │ │ └─────────────────────────────────────────────────────┘ │ └────────────────────────────────────────────────────────────┘ ↑ ↑ ↑ │ │ │ ┌─────┴─────┐ ┌───────┴───┐ ┌────┴────┐ │ Owner │ │ Reader 1 │ │Reader 2 │ │ (Producer)│ │ (Consumer)│ │(Consumer)│ └───────────┘ └───────────┘ └─────────┘ │ ↓ 数据变化 → 写入缓冲区Owner 客户端:第一个写入开始使能的客户端,负责配置触发条件(可以写参数),开始后服务端负责生成报告并写入缓冲区
Reader 客户端:从缓冲区读取报告,互不影响
BRCB 的不同客户端角色划分
角色一:所(拥)有者客户端(Owner)
权限 说明 ✅ 设置 RptEna=true 启用报告 ✅ 设置 Resv=true 预留 BRCB ✅ 修改 DatSet 配置数据集 ✅ 触发 GI 发起总召唤 ✅ 执行 PurgeBuf 清空缓冲区 ✅ 读取缓冲区 读取报告 角色二:读取者客户端(Reader)
权限 说明 ❌ 设置 RptEna=true 被拒绝 ❌ 设置 Resv=true 被拒绝 ❌ 修改 DatSet 被拒绝 ❌ 触发 GI 被拒绝 ❌ 执行 PurgeBuf 被拒绝 ✅ 读取缓冲区 可以读取!
五、代码实现关键要点
5.1 URCB 关键代码
| 方法 | 功能 | 位置 |
|---|---|---|
enable() | 启用 URCB,注册监听器 | Urcb.java#L49 |
disable() | 禁用 URCB,取消注册 | Urcb.java#L100 |
report() | 生成并发送报告 | Urcb.java#L284 |
getMmsReport() | 生成 MMS PDU | Urcb.java#L158 |
5.2 BRCB 关键代码
| 方法 | 功能 | 位置 |
|---|---|---|
enable() | 启用 BRCB,注册监听器 | Brcb.java#L319 |
disable() | 禁用 BRCB,取消注册 | Brcb.java#L354 |
writeReportToBuffer() | 写入缓冲区 | Brcb.java#L87 |
getBufferedReports() | 读取缓冲区 | Brcb.java#L280 |
purgeBuffer() | 清空缓冲区 | Brcb.java#L287 |
generateMmsReportPdu() | 生成 MMS PDU | Brcb.java#L126 |
六、总结
6.1 选择建议
| 需求场景 | 推荐选择 | 理由 |
|---|---|---|
| 实时监控告警 | URCB | 实时推送,及时响应 |
| 历史数据查询 | BRCB | 支持缓冲区,可查询历史 |
| 多客户端访问 | BRCB | 读取共享,多个客户端可访问 |
| 控制操作反馈 | URCB | 实时性要求高 |
| 故障分析 | BRCB | 可追溯历史事件 |
| 低带宽网络 | BRCB | 按需读取,减少流量 |
6.2 核心区别
URCB强调实时性和独占性,适合需要立即响应的场景。
BRCB强调数据持久化和共享访问,适合需要历史查询和多客户端访问的场景。
两者互补,共同构成 IEC 61850 标准中完整的报告机制。