Session 会话 — OpcUaSession
OpcUaSession 是 Java SDK 的 Client 主类 (对应 C# 的 DarraOpcUa), 一个实例对应一个 OPC UA Session. 所有访问 (Read / Write / Browse / Subscribe / Call / History) 都从这个对象出发.
实现 AutoCloseable, 必须在 try-with-resources 中使用, 否则会泄漏 native 资源 + 服务端 Session.
子页跳转
- 构造与连接参数请参考 构造函数.
- 连接 / 断开请参考 连接管理.
- 单点 / 批量读写请参考 Read / Write.
- 内部事件统一通道请参考 Events.
- 命名空间反查请参考 Namespaces.
- 心跳与会话保活请参考 KeepAlive.
公共字段 / 属性
| 类别 | 属性 | 类型 | 访问 | 说明 |
|---|---|---|---|---|
| 连接 | getEndpointUrl() | String | R | 构造时指定的 endpoint URL |
getSecurityMode() | Enums.MessageSecurityMode | R | 安全模式 (None / Sign / SignAndEncrypt) | |
| 状态 | getState() | Enums.SessionState | R | 当前会话状态 (Disconnected / Connecting / Connected / Reconnecting / Closing / Failed) |
isConnected() | boolean | R | 是否已连接 (= getState() == Connected) | |
| 子对象 | nodes | NodeCollection | R | Lazy Load 节点访问器 (final 字段) |
namespaces | NamespaceCollection | R | 命名空间 URI ↔ Index 互转 (final 字段) | |
| 事件 | events | OpcUaEvents | R | 会话级事件统一通道 (Connected / Disconnected / DataChange / ServerEvent / ...) (final 字段) |
| 配置 | getKeepAliveIntervalMs() / setKeepAliveIntervalMs(int) | int | RW | KeepAlive 心跳周期 (默认 10000 ms, 0 = 禁用) |
isAutoPublish() / setAutoPublish(boolean) | boolean | RW | 启停后台 Publish 线程 (connect 后默认 true) | |
| 内部 | handle() | int | R | C 层句柄 (调试用) |
公共方法
连接管理
| 方法 | 说明 |
|---|---|
connect() | 建立连接 (Hello → SecureChannel → Session → Activate) |
disconnect() | 主动断开, 实例可重连 |
close() | 释放资源, 自动 disconnect (来自 AutoCloseable) |
心跳与发布
| 方法 | 说明 |
|---|---|
publish(int timeoutMs) | 手动触发一次 Publish (一般无需调用) |
读 / 写
| 方法 | 说明 |
|---|---|
read(String nodeId) | 读单节点 Value Attribute |
read(nodeId, AttributeId) | 读单节点指定 Attribute |
readMany(List<String>, AttributeId) | 批量读 (单 Attribute) |
write(nodeId, OpcUaVariant) | 写单节点 Value |
write(nodeId, OpcUaVariant, AttributeId) | 写单节点指定 Attribute |
浏览
| 方法 | 说明 |
|---|---|
browse(nodeId) / browse(nodeId, NodeClass) | 单层浏览 |
browseMany(List<String>, NodeClass) | 批量浏览 |
browseWithPaging(nodeId, NodeClass) | 含 ContinuationPoint 翻页支持 |
browseNext(byte[] cp, boolean release) | 续翻分页 |
browseAll(nodeId) / browseAll(nodeId, filter, maxPages) | 自动分页拉全 |
translateBrowsePaths(List<Map.Entry<String,String>>) | 路径批量解析为 NodeId |
translateBrowsePathsAt(start, paths) | 同起点的便捷重载 |
resolve(path) | 单条绝对路径解析 |
resolve(startNodeId, path) | 单条相对路径解析 |
registerNodes(List<String>) | 注册临时高效 NodeId |
unregisterNodes(List<String>) | 注销临时 NodeId |
订阅
| 方法 | 说明 |
|---|---|
createSubscription(double publishingIntervalMs) | 创建数据订阅 |
subscribeEvents() | 订阅 Server 事件 (默认 i=2253) |
subscribeEvents(nodeId) | 订阅指定节点事件 |
subscribeEvents(nodeId, existingSub) | 复用已有订阅容器 |
transferSubscriptions(List<Integer>, boolean) | 跨 Session 迁移订阅 |
方法调用
| 方法 | 说明 |
|---|---|
call(objectId, methodId, OpcUaVariant... inputs) | 调用 OPC UA Method 节点 |
历史
| 方法 | 说明 |
|---|---|
readHistory(nodeId, Instant start, Instant end, int maxValues) | 读原始历史 |
readHistoryModified(nodeId, start, end, maxValues, returnBounds) | 读含修改记录的历史 |
readHistoryAtTime(nodeId, List<Instant> times, useSimpleBounds) | 读指定时间点的内插值 |
readHistoryProcessed(nodeId, start, end, processingMs, aggregateNodeId) | 聚合 (Avg / Min / Max / TimeAverage / ...) |
readHistoryEvents(nodeId, start, end, maxEvents) | 读历史事件 |
updateHistory(nodeId, HistoryUpdateType, List<OpcUaDataValue>) | Insert / Replace / Update / Remove 历史 |
deleteHistoryRange(nodeId, start, end, deleteModifiedToo) | 按时间段删除历史 |
控制
| 方法 | 说明 |
|---|---|
cancel(int requestHandle) | 取消未完成请求 |
完整示例
import com.darra.opcua.*;
import com.darra.opcua.OpcUaEvents.ConnectionEventArgs;
try (OpcUaSession ua = new OpcUaSession("opc.tcp://localhost:4840")) {
ua.events.onConnected.add(e ->
System.out.println("Connected to " + e.endpointUrl));
ua.events.onDisconnected.add(e ->
System.out.println("Disconnected: " + e.message));
ua.connect();
// 读
try (OpcUaDataValue dv = ua.read("ns=2;s=Temperature")) {
System.out.println("T = " + dv.variant().asDouble() + " °C");
}
// 写
try (OpcUaVariant v = new OpcUaVariant().setDouble(42.0)) {
Enums.StatusCode st = ua.write("ns=2;s=Setpoint", v);
System.out.println("Write status = " + st);
}
// 订阅
try (OpcUaSubscription sub = ua.createSubscription(500.0)) {
sub.add("ns=2;s=Counter", e ->
System.out.println(e.nodeId + " = " + e.valueString + " (" + e.status + ")"));
Thread.sleep(60_000);
}
}