跳到主要内容

read_history_events

如果服务端记录事件历史 (HistoryRead Events), 客户端可以按时间区间拉历史事件.

配套

签名

pub fn Session::read_history_events(
&self,
node_id: &str, // 通常 well_known_nodes::SERVER ("i=2253")
start: SystemTime,
end: SystemTime,
max_events: u32,
) -> Result<Vec<EventArrivedEventArgs>, OpcUaError>;

EventArrivedEventArgs 字段

pub struct EventArrivedEventArgs {
pub severity: u16,
pub message: Option<String>,
pub source_name: Option<String>,
pub time: Option<SystemTime>,
pub event_type: Option<String>,
}

服务端返回的每条事件已被 SDK 抽取为这 5 个标准字段 (默认 SelectClauses: Severity / Message / SourceName / Time, EventType 通过 BrowsePath 拿到).


用法

use std::time::{Duration, SystemTime};
use darra_opcua::well_known_nodes;

let now = SystemTime::now();
let yesterday = now - Duration::from_secs(86400);

let events = s.read_history_events(
well_known_nodes::SERVER,
yesterday, now,
/*max*/ 1000,
)?;

for e in &events {
println!("[{}] {:?}: {:?} @ {:?}",
e.severity, e.source_name, e.message, e.time);
}

自定义 EventFilter

当前 SDK 用内置 SelectClauses (Severity / Message / SourceName / Time), 自定义过滤 EventType / Severity 等待后续版本暴露 builder API.

服务端要求

  • 必须支持 HistoryRead Events (服务端 ServerCapabilities 标志位)
  • 事件源节点必须有 EventNotifier Attribute (12) bit 1 (HistoryRead) 置位

与实时事件订阅的关系

API拿什么
Session::subscribe_events(...)实时事件 (订阅期间发生的)
Session::read_history_events(...)历史事件 (服务端归档的)

通常组合用: 启动时 read_history_events 拉过去 24 小时, 然后 subscribe_events 接管实时:

// 启动时拉历史
let history = s.read_history_events(
well_known_nodes::SERVER,
SystemTime::now() - Duration::from_secs(86400),
SystemTime::now(),
1000,
)?;
for e in &history {
println!("HISTORY [{}] {:?}", e.severity, e.message);
}

// 然后订阅实时
let _live = s.subscribe_events(None, None, |e| {
println!("LIVE [{}] {:?}", e.severity, e.message);
})?;

错误

StatusCode原因
BAD_HISTORY_OPERATION_UNSUPPORTED服务端不支持 HistoryRead Events
BAD_INVALID_ARGUMENTstart/end 无效
DARRA_INVALID_ARGUMENTnode_id 含 NUL

下一步