跳到主要内容

订阅自恢复

概述

Session 重连后, 服务端 Subscription 可能仍存活也可能已被清理。SDK 两步走:

  1. TransferSubscriptions — 把旧 SubscriptionId 转给新 Session
  2. Recreate — 失败时, 按缓存重建 Sub + 全部 MI

业务侧无需手动处理。

API

方法 / 事件类别读写说明
ua.TransferSubscriptions(old_sub_ids, send_initial_values)方法转移订阅
events.OnSubscriptionLost(callback)事件订阅丢失
events.OnSubscriptionRestored(callback)事件订阅恢复

代码示例

#include <darra/opcua.h>
using namespace darra::opcua;

DarraOpcUa ua("opc.tcp://localhost:4840");

ua.Events().OnSubscriptionLost([](const SubscriptionLostEventArgs& e) {
std::cerr << "订阅丢失: sub_id=" << e.subscription_id << "\n";
});
ua.Events().OnSubscriptionRestored([](const OpcUaEventEntry& e) {
std::cout << "订阅已恢复: " << e.source << "\n";
});

ua.Connect();

// 创建 sub + MI, 全程不变
auto sub = ua.CreateSubscription(500);
DataChangeFilter filter{ .deadband_type = DeadbandType::Absolute, .deadband_value = 0.5 };
auto mi = sub->Add("ns=2;s=Temp", AttributeId::Value, 200,
MonitoringMode::Reporting, 10, true, &filter);

sub->OnDataChanged([](const DataChangeEventArgs& e) {
std::cout << e.value.value << " @ " << e.value.source_timestamp << "\n";
});

// 拔网线 30 秒, 看日志:
// Reconnecting → Reconnected → SubscriptionRestored
// 数据自动续上, filter 也保留

// 手动 transfer
auto rcs = ua.TransferSubscriptions({ sub->SubscriptionId() }, /*send_initial_values=*/true);

恢复流程

重连成功

对每个本地 Subscription:
1. TransferSubscriptions(old_sub_id)
├─ Good → SubscriptionRestored 事件
└─ BadSubscriptionIdInvalid → 进入 2
2. CreateSubscription(original_params) 拿新 sub_id
3. 按本地 _mi_cache 重建所有 MI
- SamplingInterval / Mode / QueueSize / DiscardOldest
- DataChangeFilter
- EventFilter
- Triggering Links
4. SubscriptionRestored 事件

缓存的字段

_mi_cache 保留: NodeId / AttributeId / SamplingInterval / Mode / QueueSize / DiscardOldest / DataChangeFilter / EventFilter。

恢复时全部重放, 服务端 mi id 会变, 业务侧应使用 client_handle 而非 server-side id 对账。

最佳实践

  • 业务用 client_handle, 不要持久化 mi id
  • 监听 OnSubscriptionRestored
  • 不要在 OnSubscriptionLost 里手动 recreate
  • 关键参数变更后 pause 再 resume

跨语言对照

C#PythonJavaC++RustC
TransferSubscriptionstransfer_subscriptionstransferSubscriptionsTransferSubscriptionstransfer_subscriptionsDarraUa_Session_TransferSubscriptions

下一步