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

OPC Foundation SDK订阅功能使用及回调函数添加问题咨询

问题根因

你当前的代码仅完成了服务端侧订阅、监控项的资源创建,缺少两个核心逻辑:1. 客户端侧的通知回调处理器绑定 2. 发布请求(PublishRequest)的轮询触发逻辑,OPC UA协议规定订阅的通知数据由客户端主动发送PublishRequest拉取,没有这步自然无法触发回调。

具体解决步骤

1. 补全订阅创建的必要参数

你当前的CreateSubscriptionRequest没有显式开启发布开关,先补全配置:

CreateSubscriptionRequest req  = new CreateSubscriptionRequest();
req.setRequestedPublishingInterval(250D);
// 新增开启发布、最大保留通知数等配置
req.setRequestedMaxKeepAliveCount(UnsignedInteger.valueOf(10));
req.setRequestedLifetimeCount(UnsignedInteger.valueOf(100));
req.setPublishingEnabled(true); // 必须显式开启发布

2. 绑定通知回调监听器

给你获取的sessionChannel绑定通知处理监听器,回调逻辑写在监听器里:

sessionChannel.setNotificationListener(new NotificationListener() {
    @Override
    public void onNotificationData(UnsignedInteger subscriptionId, List<MonitoredItemNotification> notifications) {
        // 匹配对应订阅ID后处理数据
        if (subscriptionId.equals(subid)) {
            for (MonitoredItemNotification notification : notifications) {
                // 拿到监控项的数值变化
                DataValue value = notification.getValue();
                System.out.println("收到数值更新:" + value.getValue().getValue());
                // 你的业务逻辑写在这里
            }
        }
    }

    @Override
    public void onStatusChangeNotification(UnsignedInteger subscriptionId, StatusChangeNotification statusChange) {
        // 订阅状态变化的回调处理
        System.out.println("订阅状态变化:" + statusChange.getStatus());
    }
});

3. 启动PublishRequest轮询线程

需要单独开一个守护线程循环发送PublishRequest,拉取服务端的通知数据,触发上面的回调:

new Thread(() -> {
    while (!sessionChannel.isClosed()) {
        try {
            PublishRequest publishRequest = new PublishRequest();
            // 简单实现可先传空的确认序列
            publishRequest.setSubscriptionAcknowledgements(new SubscriptionAcknowledgement[0]);
            sessionChannel.Publish(publishRequest);
            // 间隔略小于发布间隔即可,避免请求过于频繁
            Thread.sleep(100);
        } catch (InterruptedException e) {
            break;
        } catch (ServiceException e) {
            // 处理服务异常,可根据业务需要加重试逻辑
            e.printStackTrace();
        }
    }
}, "opc-ua-publish-thread").start();

4. 补充监控项创建校验逻辑

可以加一步判断监控项是否创建成功,避免配置错误导致无回调触发:

CreateMonitoredItemsResponse crp = sessionChannel.CreateMonitoredItems(null,subid,TimestampsToReturn.Both,mrs);
// 新增校验逻辑
MonitoredItemCreateResult result = crp.getResults()[0];
if (result.getStatusCode().isBad()) {
    System.out.println("监控项创建失败:" + result.getStatusCode());
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 06:15:07