Eclipse Milo Client SDK是否支持SCAN模式采集数据
Milo客户端对SCAN采集模式的支持情况
Eclipse Milo OPC UA客户端没有提供开箱即用、命名为「SCAN」的预置采集模块,但底层原生API完全支撑你描述的SCAN模式实现——也就是定时器运行在客户端侧、对OPC UA服务端来说等价于普通按需读取的采集逻辑,不需要依赖服务端托管的Subscription订阅能力。
和Subscription模式的核心差异是:SCAN模式的调度逻辑完全在客户端侧维护,不会在服务端创建订阅资源、不会产生服务端主动推送的流量,适合对采集周期灵活性要求高、或者服务端资源受限不适合创建大量订阅的场景。
SCAN模式实现涉及的核心类说明
实现SCAN采集不需要用到Milo的订阅相关模块,核心依赖以下几类:
OpcUaClient:Milo客户端的核心交互入口类,SCAN场景下核心用到两个读方法:read(double maxAge, TimestampsToReturn timestamps, List<ReadValueId> nodes):支持自定义点位值最大允许缓存时间、返回的时间戳类型,适合需要精细化控制读参数的场景readValues(List<NodeId> nodeIds):封装好的批量读方法,直接传入点位ID列表即可批量拿到点位值,默认返回源时间戳、允许最大缓存年龄为0(即强制读服务端最新值),是SCAN场景最常用的方法
NodeId:OPC UA网络中唯一标识一个点位的实体类,所有需要SCAN采集的点位都要先构造对应的NodeId实例,作为读请求的入参。DataValue:点位读结果的封装类,包含三个核心信息:点位的变量值、质量戳(标识值是否有效)、源时间戳(点位值在数据源生成的时间)/服务端时间戳(服务端拿到值的时间),是SCAN采集结果的原始载体。ScheduledExecutorService:JDK原生提供的定时任务线程池,SCAN模式的客户端侧定时调度逻辑直接基于该类实现即可,不需要引入额外的调度框架,也不需要依赖Milo的内部调度能力。实际使用时建议按采集周期分组配置调度任务,同周期的点位合并为一次批量读请求,避免大量单点位请求占用带宽。StatusCode:OPC UA状态码封装类,每一个DataValue中都会携带对应的StatusCode,用来标识该点位读操作是否成功,常见的错误码包括点位不存在、无读权限、服务端暂时不可用等,SCAN逻辑中需要遍历批量返回的结果,逐个校验状态码做异常处理。UaException:Milo客户端交互过程中抛出的异常类,网络断连、请求超时、服务端返回全局错误等场景会抛出该异常,SCAN任务中需要捕获该类异常,做断线重连、失败重试、采集状态标记等处理。
实现SCAN模式的关键注意点
- 禁止为每个点位单独创建定时任务,必须按采集周期对点位分组,同组点位批量发起读请求,否则会产生大量冗余网络请求,大幅提升客户端和服务端的负载。
- 配置调度周期时要留足冗余,确保单批次读请求的平均响应时间远小于调度周期,避免任务堆积导致客户端内存溢出。
- 批量读请求的单次点位数量建议控制在1000以内,点位总量大时可以拆分为多个批次错峰调度,避免单次请求报文过大导致传输超时。
内容的提问来源于stack exchange,提问作者Jai kishan Sharma
相关产品推荐
相关产品推荐

