read_history_events
如果服务端记录事件历史 (HistoryRead Events), 客户端可以按时间区间拉历史事件.
配套
- 实时事件订阅请用 事件订阅.
- 历史变量数据请用 ReadRaw / ReadProcessed.
签名
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 标志位)
- 事件源节点必须有
EventNotifierAttribute (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_ARGUMENT | start/end 无效 |
DARRA_INVALID_ARGUMENT | node_id 含 NUL |