跳到主要内容

Events — ua.events.*

OpcUaSession.events 是 SDK 内部事件统一通道, 把会话生命周期 / 订阅生命周期 / 数据变化 / 通讯异常都汇集到一个对象上, 方便上层 UI 做日志 / 状态栏 / 调试.

Java 没有原生 event 关键字, 用 List<Consumer<...>> (CopyOnWriteArrayList) 替代 — 用户直接 add(consumer) / remove(consumer).

与 OPC UA 协议事件区分
  • ua.events.* — SDK 内部事件 (本节, 与协议无关)
  • ua.subscribeEvents(...) — OPC UA 协议事件 (Alarms & Conditions), 见 事件订阅

完整事件清单

会话生命周期

字段EventArgs 类型触发时机
events.onConnectedConnectionEventArgs首次连接成功
events.onDisconnectedConnectionEventArgs主动 / 被动断开
events.onReconnectingConnectionEventArgs检测到断线, 启动自动重连
events.onReconnectedConnectionEventArgs自动重连成功
events.onKeepAliveKeepAliveEventArgsKeepAlive 心跳成功
events.onStateChangedSessionStateChangedEventArgs任何 SessionState 变化

异常

字段EventArgs 类型触发时机
events.onCommunicationErrorCommunicationErrorEventArgs通讯失败 (KeepAlive 失败 / Read 异常等)
events.onSubscriptionLostSubscriptionLostEventArgs订阅被服务端清理

统一通道

字段EventArgs 类型触发时机
events.onAnyOpcUaEventEntry所有事件汇集 (Connected / Disconnected / DataChange / Read / Write / Browse / Call / HistoryRead / Alarm / ...)

OpcUaEventEntry 字段: category (Enums.OpcUaEventCategory) + severity (Enums.OpcUaEventSeverity) + source + message + statusCode + timestampUtc + original.


OpcUaEventCategory 枚举

OpcUaEventEntry.category 字段, 完整清单:

Unknown,
Connected, Disconnected, Reconnecting, Reconnected, KeepAlive, StateChanged,
SubscriptionCreated, SubscriptionLost, SubscriptionRestored,
MonitoredItemAdded, MonitoredItemRemoved, SubscriptionCleared,
DataChange, ServerEvent, Alarm,
Read, Write, Browse, Call, HistoryRead,
CommunicationError, SecurityError, ProtocolError,
Info, Diagnostic

OpcUaEventSeverity 枚举

Trace, Debug, Info, Warn, Error, Fatal

用法示例

通用日志钩子 (一行打印 SDK 内所有事件)

ua.events.onAny.add(e ->
System.out.printf("[%s] [%s] %s: %s (%s)%n",
e.severity, e.category, e.source, e.message, e.statusCode));

调试期非常省事 — 不订阅具体事件, 一行 hook 看全部.

状态栏绑定 (Swing)

import javax.swing.SwingUtilities;

ua.events.onStateChanged.add(e -> {
SwingUtilities.invokeLater(() -> {
statusLabel.setText(e.newState.toString());
statusLabel.setForeground(e.newState == Enums.SessionState.Connected
? Color.GREEN : Color.RED);
});
});

错误统计

java.util.concurrent.atomic.AtomicInteger errorCount = new java.util.concurrent.atomic.AtomicInteger();
ua.events.onCommunicationError.add(e -> errorCount.incrementAndGet());

与订阅 onDataChanged 的关系

订阅 sub.onDataChanged 仅收到该订阅的事件; ua.events.onAny (Category=DataChange) 收到 SDK 下所有订阅的事件 (统一通道). 两者并存, 上层按场景选用:

  • 单订阅业务逻辑 → sub.onDataChanged.add(...)
  • 全局日志 / 录波 / 调试 → ua.events.onAny.add(...)

线程模型

必须切回 UI 线程

事件回调在 C 层 Publish 线程上调用, 不在调用方线程. UI 操作必须 SwingUtilities.invokeLater (Swing) / Platform.runLater (JavaFX) 切回 UI 线程, 否则跨线程 UI 操作会崩.

不要在事件里执行长操作 (>100 ms), 否则会阻塞 Publish 队列.

回调里抛异常会被 SDK 吞掉 (try-catch ignored), 不会传播到 native, 不会让 Stack 闪退.

下一步