跳到主要内容

Session 会话 — darra::opcua::Session

Session 是 Client 主类, 一个实例对应一个 OPC UA Session. 所有访问 (Read / Write / Browse / Subscribe / Call / History) 都从这个对象出发. Move-only, 析构自动 Disconnect + 释放 native handle.

#include <darra/opcua/client.hpp>
using namespace darra::opcua;
子页跳转

公共访问器

类别属性类型访问说明
连接EndpointUrl()std::string const&R构造时指定的 endpoint URL
Config()ConnectionConfig const&R完整连接配置 (含 SecurityMode 等)
Handle()DarraUa_SessionHandleRC 层句柄 (内部用)
状态State()SessionStateR当前会话状态 (Disconnected / Connecting / Connected / Reconnecting / Closing / Failed)
IsConnected()boolR等价 State() == Connected
子对象Nodes()NodeCollection&RLazy Load 节点访问器
NamespacesRef()Namespaces&R命名空间表
Events()SessionEvents&R会话级事件 (字段式 std::function)
配置SetKeepAliveInterval(ms)voidWKeepAlive 心跳周期 (默认 10000 ms, 0 = 禁用)
AutoPublish() / SetAutoPublish(bool)boolRW启停后台 Publish 线程 (默认 true)

公共方法

连接管理

  • Connect() — 建立连接 (Hello → SecureChannel → Session → Activate)
  • Disconnect() — 主动断开, 实例可重连
  • ~Session() — 析构自动 Disconnect + 释放 handle (RAII)

心跳与发布

  • Publish(timeout_ms = 2000) — 手动触发一次 Publish (一般无需调用)
  • StartAutoPublish() / StopAutoPublish() — 启停后台 Publish 线程

读 / 写

浏览

订阅

方法调用

历史

控制

  • Cancel(request_handle) — 取消未完成请求

Move-only 语义

Session s("opc.tcp://localhost:4840");
// Session s2 = s; // 编译错误: copy ctor deleted
Session s2 = std::move(s); // OK, s 此后失效

完整示例

#include <darra/opcua/client.hpp>
#include <iostream>

using namespace darra::opcua;

int main() {
Stack::Init();
Session s("opc.tcp://localhost:4840");

s.Events().on_connected = [](std::string const& url) {
std::cout << "Connected to " << url << "\n";
};
s.Events().on_disconnected = [](std::string const& url, Status reason) {
std::cout << "Disconnected from " << url
<< " reason=0x" << std::hex << static_cast<uint32_t>(reason) << "\n";
};

s.Connect();

// 读
auto dv = s.Read("ns=2;s=Temperature");
double t = 0; dv.Value().TryGetDouble(t);
std::cout << "T = " << t << " degC\n";

// 写
Variant v; v.SetDouble(42.0);
auto st = s.Write("ns=2;s=Setpoint", v);
std::cout << "Write status = 0x" << std::hex << static_cast<uint32_t>(st) << "\n";

// 订阅
auto sub = s.CreateSubscription(500.0);
sub.AddNode("ns=2;s=Counter", [](DataValue const& dv) {
std::cout << dv.Value().AsString() << "\n";
});

// 方法
std::vector<Variant> args;
{ Variant a; a.SetInt32(3); args.push_back(std::move(a)); }
{ Variant b; b.SetInt32(4); args.push_back(std::move(b)); }
auto outs = s.Call("ns=2;s=Calc", "ns=2;s=Calc.Add", args);
for (auto const& o : outs) {
int32_t sum = 0; o.TryGetInt32(sum);
std::cout << "sum = " << sum << "\n";
}

std::this_thread::sleep_for(std::chrono::minutes(1));
Stack::Shutdown();
return 0;
}

下一步