You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何订阅OPC UA Server对象获取所有事件(Prosys Java SDK)

监听Server对象所有事件的Prosys Java SDK实现方案

问题原因

直接订阅Server节点默认仅会接收该节点自身产生的事件,子节点的事件不会自动被包含,必须通过配置事件过滤器的筛选条件,指定要接收Server层级下所有节点的事件。

实现步骤与代码示例

1. 获取Server节点

首先获取OPC UA Server对象的NodeId,Prosys SDK可通过内置标识符直接获取:

import com.prosysopc.ua.client.UaClient;
import com.prosysopc.ua.nodes.UaNode;
import com.prosysopc.ua.stack.builtintypes.NodeId;
import com.prosysopc.ua.stack.core.Identifiers;

// 假设client已完成初始化与连接
UaNode serverNode = client.getAddressSpace().getNode(Identifiers.Server);
NodeId serverNodeId = serverNode.getNodeId();

2. 构建事件过滤器

使用EventFilterBuilder创建包含层级筛选规则的过滤器,核心是添加IsDescendantOf条件,匹配所有来自Server节点及其子节点的事件:

import com.prosysopc.ua.stack.core.AttributeOperand;
import com.prosysopc.ua.stack.core.ContentFilter;
import com.prosysopc.ua.stack.core.ContentFilterElement;
import com.prosysopc.ua.stack.core.EventFilter;
import com.prosysopc.ua.stack.core.EventFilterBuilder;
import com.prosysopc.ua.stack.core.FilterOperator;
import com.prosysopc.ua.stack.core.LiteralOperand;

EventFilterBuilder filterBuilder = new EventFilterBuilder();

// 添加需要获取的事件字段(可根据业务需求调整)
filterBuilder.addSelectClause(Identifiers.EventType);
filterBuilder.addSelectClause(Identifiers.SourceNode);
filterBuilder.addSelectClause(Identifiers.Message);
filterBuilder.addSelectClause(Identifiers.Time);
filterBuilder.addSelectClause(Identifiers.Severity);

// 添加筛选条件:仅接收SourceNode是Server节点或其子节点的事件
ContentFilterElement hierarchyCondition = new ContentFilterElement(
        FilterOperator.IsDescendantOf,
        new[] {
                // 取事件的SourceNode属性
                new AttributeOperand(Identifiers.BaseEventType, Identifiers.SourceNode, null, null),
                // 目标节点:Server节点
                new LiteralOperand(new NodeId(serverNodeId.getNamespaceIndex(), serverNodeId.getValue()))
        }
);
filterBuilder.setWhereClause(new ContentFilter(new[] {hierarchyCondition}));

EventFilter eventFilter = filterBuilder.build();

3. 创建订阅并绑定事件回调

创建订阅实例,将带有过滤器的监控项绑定到Server节点,并注册事件处理逻辑:

import com.prosysopc.ua.client.MonitoredItem;
import com.prosysopc.ua.client.Subscription;
import com.prosysopc.ua.stack.core.MonitoringMode;
import com.prosysopc.ua.stack.core.MonitoringParameters;
import com.prosysopc.ua.stack.core.MonitoredItemCreateRequest;
import com.prosysopc.ua.stack.core.TimestampsToReturn;
import com.prosysopc.ua.stack.builtintypes.LocalizedText;
import com.prosysopc.ua.stack.builtintypes.DateTime;
import com.prosysopc.ua.stack.builtintypes.UaInteger;

// 创建订阅(刷新间隔1000ms,可按需调整)
Subscription subscription = client.getSubscriptionManager().createSubscription(1000);

// 创建事件监控项请求
MonitoredItemCreateRequest itemRequest = new MonitoredItemCreateRequest(
        new ReadValueId(serverNodeId, Attributes.EventNotifier, null, null),
        MonitoringMode.Reporting,
        new MonitoringParameters(
                UaInteger.valueOf(client.getSubscriptionManager().getNextMonitoredItemId()),
                0.0, // 事件订阅采样间隔可设为0
                null,
                UaInteger.valueOf(100), // 队列大小
                true // 队列满时丢弃旧事件
        )
);
// 绑定事件过滤器
itemRequest.getMonitoringParameters().setFilter(eventFilter);

// 添加监控项到订阅
subscription.createMonitoredItems(TimestampsToReturn.Both, List.of(itemRequest));

// 注册事件消费者,处理收到的事件
for (MonitoredItem item : subscription.getMonitoredItems()) {
    item.setEventConsumer((monitoredItem, eventFields) -> {
        // 解析事件字段(顺序与SelectClauses定义一致)
        NodeId eventType = (NodeId) eventFields[0].getValue().getValue();
        NodeId sourceNode = (NodeId) eventFields[1].getValue().getValue();
        LocalizedText message = (LocalizedText) eventFields[2].getValue().getValue();
        DateTime eventTime = (DateTime) eventFields[3].getValue().getValue();
        Integer severity = (Integer) eventFields[4].getValue().getValue();

        // 自定义事件处理逻辑
        System.out.printf("事件触发 | 类型: %s | 来源节点: %s | 消息: %s | 时间: %s | 级别: %d%n",
                eventType, sourceNode, message.getText(), eventTime, severity);
    });
}

关键注意事项

  • 确保Server节点的EventNotifier属性支持事件订阅(默认Server节点均满足该条件)。
  • 可根据业务需求调整SelectClauses,添加或移除需要的事件属性。
  • 如果需要监听特定类型的事件,可在WhereClause中追加EventType的匹配条件。

内容的提问来源于stack exchange,提问作者WickedXXX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 03:42:49