跳到主要内容

Subscription 订阅

Subscription 是订阅容器, 管理一批 MonitoredItem (MI), 通过回调闭包接收 DataChange 通知.

子页跳转

一分钟速览

use darra_opcua::{Session, AttributeId, MonitoringMode};

let mut s = Session::new("opc.tcp://localhost:4840")?;
s.connect()?;

// 创建
let sub = s.create_subscription(500.0)?;

// 添加单 MI + 闭包回调
sub.add_node("ns=2;s=Counter", |args| {
println!("{:?} = {:?} ({})",
args.node_id, args.value_string, args.status);
})?;
sub.add_node("ns=2;s=Temperature", |args| {
println!("temp = {:?}", args.value_string);
})?;

// 批量添加 (共享一个回调)
let nodes: Vec<String> = (1..=100).map(|i| format!("ns=2;s=T{}", i)).collect();
let nodes_ref: Vec<&str> = nodes.iter().map(String::as_str).collect();
let results = sub.add_many(&nodes_ref, AttributeId::Value, |args| {
println!("{:?} = {:?}", args.node_id, args.value_string);
})?;

// 改单个 MI 的采样间隔
let h = results[0].0;
sub.modify_item(h, 100.0, 1, true)?;

// 暂停 / 恢复
sub.set_mode(h, MonitoringMode::Disabled)?;
sub.set_mode(h, MonitoringMode::Reporting)?;

// 移除单个
sub.remove(h);

// 子作用域结束时 sub Drop, 自动 _Subscription_Delete 清理所有 MI

订阅生命周期事件

通过 s.events.lock().unwrap().on_any 统一通道收:

use darra_opcua::OpcUaEventCategory;

s.events.lock().unwrap().on_any.push(Box::new(|e| {
match e.category {
OpcUaEventCategory::SubscriptionCreated => println!("sub created: {}", e.source),
OpcUaEventCategory::MonitoredItemAdded => println!("mi added: {}", e.source),
OpcUaEventCategory::MonitoredItemRemoved => println!("mi removed: {}", e.source),
OpcUaEventCategory::SubscriptionLost => println!("sub lost: {}", e.source),
_ => {}
}
}));

详见 Session 事件.


Drop 自动清理

{
let sub = s.create_subscription(500.0)?;
sub.add_node("ns=2;s=X", |_| {})?;
// ... 用 sub ...
} // <- sub Drop, 自动 _Subscription_Delete (服务端 + 本地都清)

不需要手动调 Subscription_Delete. items 表里所有 Arc<TrampolineCtx> 自然 drop.

下一步