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;
子页跳转
- 构造与连接参数请参考 构造函数.
- 连接 / 断开请参考 连接管理.
- 单点 / 批量读写请参考 Read / Write.
- 内部事件统一通道请参考 Events.
- 命名空间反查请参考 Namespaces.
- 心跳与会话保活请参考 KeepAlive.
公共访问器
| 类别 | 属性 | 类型 | 访问 | 说明 |
|---|---|---|---|---|
| 连接 | EndpointUrl() | std::string const& | R | 构造时指定的 endpoint URL |
Config() | ConnectionConfig const& | R | 完整连接配置 (含 SecurityMode 等) | |
Handle() | DarraUa_SessionHandle | R | C 层句柄 (内部用) | |
| 状态 | State() | SessionState | R | 当前会话状态 (Disconnected / Connecting / Connected / Reconnecting / Closing / Failed) |
IsConnected() | bool | R | 等价 State() == Connected | |
| 子对象 | Nodes() | NodeCollection& | R | Lazy Load 节点访问器 |
NamespacesRef() | Namespaces& | R | 命名空间表 | |
Events() | SessionEvents& | R | 会话级事件 (字段式 std::function) | |
| 配置 | SetKeepAliveInterval(ms) | void | W | KeepAlive 心跳周期 (默认 10000 ms, 0 = 禁用) |
AutoPublish() / SetAutoPublish(bool) | bool | RW | 启停后台 Publish 线程 (默认 true) |
公共方法
连接管理
| 方法 | 说明 |
|---|---|
Connect() | 建立连接 (Hello → SecureChannel → Session → Activate) |
Disconnect() | 主动断开, 实例可重连 |
~Session() | 析构自动 Disconnect + 释放 handle (RAII) |
心跳与发布
| 方法 | 说明 |
|---|---|
Publish(timeout_ms = 2000) | 手动触发一次 Publish (一般无需调用) |
StartAutoPublish() / StopAutoPublish() | 启停后台 Publish 线程 |
读 / 写
| 方法 | 说明 |
|---|---|
Read(node_id, attr = AttributeId::Value) | 读单节点指定 Attribute |
ReadMany(node_ids, attr) | 批量读 (单 Attribute) |
Write(node_id, variant, attr = Value) | 写单节点 |
浏览
| 方法 | 说明 |
|---|---|
Browse(node_id, filter = Unspecified) | 单层浏览 |
BrowseMany(node_ids, filter) | 批量浏览 |
BrowseWithPaging(node_id, filter) | 含 ContinuationPoint 翻页支持 |
BrowseNext(continuation_point, release = false) | 续翻分页 |
TranslateBrowsePaths(paths) | 路径批量解析为 NodeId |
Resolve(path) | 单条绝对路径解析 |
Resolve(start_node_id, path) | 单条相对路径解析 |
RegisterNodes(node_ids) | 注册临时高效 NodeId |
UnregisterNodes(registered_ids) | 注销临时 NodeId |
订阅
| 方法 | 说明 |
|---|---|
CreateSubscription(interval_ms = 500.0) | 创建数据订阅 |
SubscribeEvents(node_id = "", existing = nullptr) | 订阅事件 (报警 / 条件) |
TransferSubscriptions(sub_ids, send_initial) | 跨 Session 迁移订阅 |
方法调用
| 方法 | 说明 |
|---|---|
Call(object_id, method_id, inputs) | 调用 OPC UA Method 节点 |
历史
| 方法 | 说明 |
|---|---|
ReadHistory(node_id, start_ft, end_ft, max_values = 0, return_bounds = false) | 读原始历史 |
ReadHistoryModified(...) | 读含修改记录的历史 |
ReadHistoryAtTime(...) | 读指定时间点的内插值 |
ReadHistoryProcessed(...) | 聚合 (Avg / Min / Max / TimeAverage / ...) |
ReadHistoryEvents(...) | 读历史事件 |
UpdateHistory(...) | Insert / Replace / Update / Remove 历史 |
DeleteHistoryRange(...) | 按时间段删除 |
控制
| 方法 | 说明 |
|---|---|
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;
}