创建 Subscription
pub fn Session::create_subscription(&self, publishing_interval_ms: f64)
-> Result<Subscription, OpcUaError>;
前置阅读 / 配套
- 添加 MonitoredItem 请看 添加 MonitoredItem.
- DataChange 字段请看 DataChange 回调.
参数
| 参数 | 默认 | 说明 |
|---|---|---|
publishing_interval_ms | 推荐 500.0 | 服务端推送数据的最小间隔, 服务端可能 revise (调整) |
例子
let sub = s.create_subscription(500.0)?;
println!("Subscription created with id={}", sub.subscription_id());
println!("Actual interval = {}ms", sub.publishing_interval_ms()); // 服务端 revised
多订阅分流
如果一个应用既要 100 ms 高频订阅 (运动数据) 又要 5000 ms 低频订阅 (环境温度), 创建 2 个 Subscription 分流, 不要混在一个里:
let fast = s.create_subscription(100.0)?;
fast.add_node("ns=2;s=AxisPosition", |args| {
println!("axis = {:?}", args.value_string);
})?;
let slow = s.create_subscription(5000.0)?;
slow.add_node("ns=2;s=AmbientTemperature", |args| {
println!("ambient = {:?}", args.value_string);
})?;
每个 Subscription 都是独立的发布节奏, 互不影响.
Subscription 公共属性
| 类别 | 属性 | 类型 | 访问 | 说明 |
|---|---|---|---|---|
| 标识 | subscription_id() | u32 | R | 服务端视角的订阅 ID (粗略, 显示用) |
handle() | u32 | R | C 层句柄 (内部用) | |
session_handle() | u32 | R | 所属 Session 句柄 | |
| 配置 | publishing_interval_ms() | f64 | R | 实际生效的发布间隔 (revised) |
set_publishing_enabled(b) | StatusCode | W | 启停整条订阅的发布 | |
| MonitoredItems | monitored_node_ids() | Vec<String> | R | 当前所有 MI 的 NodeId 快照 |
Subscription 公共方法
| 方法 | 说明 |
|---|---|
add_node(node_id, cb) | 添加单 MI |
add_node_with(node_id, attr, sampling_ms, cb) | 完整参数添加 |
add_many(node_ids, attr, cb) | 批量添加 (共享 cb) |
remove(mi_handle) | 移除单 MI |
remove_by_node_id(node_id) | 按 NodeId 移除全部对应 |
set_publishing_enabled(b) | 启停整条订阅的发布 |
pump(timeout_ms) | 手动 publish 一次 |
modify(...) | 改订阅参数 (&mut self) |
set_monitoring_mode(mode, &[mi]) | 批量切 mode |
set_mode(mi, mode) | 切单个 MI mode |
modify_monitored_items(&[req]) | 批量改采样 |
modify_item(mi, sampling_ms, queue_size, discard_oldest) | 改单 MI |
republish(seq_no) | 请求重发 |
闭包回调签名
F: FnMut(&DataChangeEventArgs) + Send + 'static
详见 DataChange 回调.
Drop 自动清理
{
let sub = s.create_subscription(500.0)?;
sub.add_node("ns=2;s=X", |_| {})?;
} // <- 此处 sub Drop, 服务端 DeleteSubscription 自动调用
C 层 Subscription_Delete 会一并清理所有 MI, 不需要逐个 remove.