使用java的milo框架访问OPCUA服务的过程是怎样的
发表于:2025-11-16 作者:千家信息网编辑
千家信息网最后更新 2025年11月16日,本篇文章给大家分享的是有关使用java的milo框架访问OPCUA服务的过程是怎样的,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。本次采
千家信息网最后更新 2025年11月16日使用java的milo框架访问OPCUA服务的过程是怎样的
本篇文章给大家分享的是有关使用java的milo框架访问OPCUA服务的过程是怎样的,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。
本次采用KEPServerEX5模拟服务端,使用milo开发的程序作为客户端
一、搭建服务端,KEPServerEX5的安装省略掉,下面是配置过程
设置通道、设备、标签

设置访问的用户名和密码

设置通过opc-ua访问的节点
二、使用milo的框架,开发客户端访问opcua服务
1、在pom文件中追击以下依赖
org.eclipse.milo sdk-client 0.2.4 org.bouncycastle bcpkix-jdk15on 1.57 org.eclipse.milo sdk-server 0.2.4
2、OPC UA协议对象接口
package com.jndj.platform.common.milo;import org.eclipse.milo.opcua.sdk.client.OpcUaClient;import org.eclipse.milo.opcua.sdk.client.api.identity.AnonymousProvider;import org.eclipse.milo.opcua.sdk.client.api.identity.IdentityProvider;import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription;import java.util.concurrent.CompletableFuture;import java.util.function.Predicate;/** * @author yaohj * @date 2020/7/30 * OPC UA协议对象接口 */public interface OpcUAClientService { /** * OPC UA服务器地址和接口 */ default String getEndpointUrl() { return "opc.tcp://127.0.0.1:49320"; } /** * 过滤返回的server endpoint */ default Predicate endpointFilter() { return e -> true; } /** * 连接服务器的安全策略 * None、Basic128Rsa15、Basic256、Basic256Sha256、Aes128_Sha256_RsaOaep、Aes256_Sha256_RsaPss */ default SecurityPolicy getSecurityPolicy() { return SecurityPolicy.None; } /** * 提供身份验证 */ default IdentityProvider getIdentityProvider() { return new AnonymousProvider(); } /** * 实际操作服务、由实现类重写实现 */ void run(OpcUaClient client, CompletableFuture future) throws Exception;} 3、OPC UA协议对象实体类
package com.jndj.platform.common.milo;import com.google.common.collect.ImmutableList;import org.eclipse.milo.opcua.sdk.client.OpcUaClient;import org.eclipse.milo.opcua.stack.core.types.builtin.*;import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;import org.springframework.stereotype.Service;import java.util.List;import java.util.concurrent.CompletableFuture;@Service("OpcUAClientService")public class OpcUAClientServiceImpl implements OpcUAClientService { /** * 覆盖接口的方法,建立和OPC UA的服务 */ @Override public void run(OpcUaClient client, CompletableFuture future) throws Exception { // 同步建立连接 client.connect().get(); // 异步读取数据 readTagData(client).thenAccept(values -> { DataValue nodeId_Tag1 = values.get(0); DataValue nodeId_Tag2 = values.get(1); System.out.println("#########Tag1=" + nodeId_Tag1.getValue().getValue()); System.out.println("#########Tag2=" + nodeId_Tag2.getValue().getValue()); future.complete(client); }); } /** * 读取标签点的数据 */ private CompletableFuture> readTagData(OpcUaClient client) { NodeId nodeId_Tag1 = new NodeId(2, "Channel1.Device1.Tag1"); NodeId nodeId_Tag2 = new NodeId(2, "Channel1.Device1.Tag2"); List nodeIds = ImmutableList.of(nodeId_Tag1, nodeId_Tag2); return client.readValues(0.0, TimestampsToReturn.Both, nodeIds); }}
4、OPC UA协议运行对象
package com.jndj.platform.common.milo;import org.eclipse.milo.opcua.sdk.client.OpcUaClient;import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig;import org.eclipse.milo.opcua.sdk.client.api.identity.UsernameProvider;import org.eclipse.milo.opcua.stack.client.UaTcpStackClient;import org.eclipse.milo.opcua.stack.core.Stack;import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Service;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;import java.util.Arrays;import java.util.concurrent.CompletableFuture;import java.util.concurrent.ExecutionException;import java.util.concurrent.TimeUnit;import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint;@Service("OpcUAClientRunner")public class OpcUAClientRunner { private final Logger logger = LoggerFactory.getLogger(getClass()); private final CompletableFuture future = new CompletableFuture<>(); private final OpcUAClientService opcUAClientService; public OpcUAClientRunner(OpcUAClientService opcUAClientService) { this.opcUAClientService = opcUAClientService; } /** * OPC UA的运行入口程序 */ public void run() { try { // 创建OPC UA客户端 OpcUaClient opcUaClient = createClient(); // future执行完毕后,异步判断状态 future.whenCompleteAsync((c, ex) -> { if (ex != null) { logger.error("连接OPC UA服务错误: {}", ex.getMessage(), ex); } // 关闭OPC UA客户端 try { opcUaClient.disconnect().get(); Stack.releaseSharedResources(); } catch (InterruptedException | ExecutionException e) { logger.error("OPC UA服务关闭错误: {}", e.getMessage(), e); } }); try { // 获取OPC UA服务器的数据 opcUAClientService.run(opcUaClient, future); future.get(5, TimeUnit.SECONDS); } catch (Throwable t) { logger.error("OPC UA客户端运行错误: {}", t.getMessage(), t); future.completeExceptionally(t); } } catch (Throwable t) { logger.error("OPC UA客户端创建错误: {}", t.getMessage(), t); future.completeExceptionally(t); } } /** * 创建OPC UA的服务连接对象 */ private OpcUaClient createClient() throws Exception { Path securityTempDir = Paths.get(System.getProperty("java.io.tmpdir"), "security"); Files.createDirectories(securityTempDir); if (!Files.exists(securityTempDir)) { throw new Exception("不能够创建安全路径: " + securityTempDir); } KeyStoreLoader loader = new KeyStoreLoader().load(securityTempDir); // 获取OPC UA的服务器端节点 EndpointDescription[] endpoints = UaTcpStackClient.getEndpoints(opcUAClientService.getEndpointUrl()).get(); EndpointDescription endpoint = Arrays.stream(endpoints) .filter(e -> e.getEndpointUrl().equals(opcUAClientService.getEndpointUrl())) .findFirst().orElseThrow(() -> new Exception("没有节点返回")); // 设置OPC UA的配置信息 OpcUaClientConfig config = OpcUaClientConfig.builder() .setApplicationName(LocalizedText.english("OPC UA SCREEN")) .setApplicationUri("urn:DATA-TRANSFER:OPC UA SCREEN") .setCertificate(loader.getClientCertificate()) .setKeyPair(loader.getClientKeyPair()) .setEndpoint(endpoint) .setIdentityProvider(new UsernameProvider("Administrator", "123456")) .setRequestTimeout(uint(5000)) .build(); // 创建OPC UA客户端 return new OpcUaClient(config); }} 5、OPC UA访问证书类
package com.jndj.platform.common.milo;import org.eclipse.milo.opcua.sdk.server.util.HostnameUtil;import org.eclipse.milo.opcua.stack.core.util.SelfSignedCertificateBuilder;import org.eclipse.milo.opcua.stack.core.util.SelfSignedCertificateGenerator;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.InputStream;import java.io.OutputStream;import java.nio.file.Files;import java.nio.file.Path;import java.security.*;import java.security.cert.X509Certificate;import java.util.regex.Pattern;class KeyStoreLoader { private final Logger logger = LoggerFactory.getLogger(getClass()); private static final Pattern IP_ADDR_PATTERN = Pattern.compile( "^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"); // 证书别名 private static final String CLIENT_ALIAS = "client-ai"; // 获取私钥的密码 private static final char[] PASSWORD = "password".toCharArray(); // 证书对象 private X509Certificate clientCertificate; // 密钥对对象 private KeyPair clientKeyPair; KeyStoreLoader load(Path baseDir) throws Exception { // 创建一个使用`PKCS12`加密标准的KeyStore。KeyStore在后面将作为读取和生成证书的对象。 KeyStore keyStore = KeyStore.getInstance("PKCS12"); // PKCS12的加密标准的文件后缀是.pfx,其中包含了公钥和私钥。 // 而其他如.der等的格式只包含公钥,私钥在另外的文件中。 Path serverKeyStore = baseDir.resolve("example-client.pfx"); logger.info("Loading KeyStore at {}", serverKeyStore); // 如果文件不存在则创建.pfx证书文件。 if (!Files.exists(serverKeyStore)) { keyStore.load(null, PASSWORD); // 用2048位的RAS算法。`SelfSignedCertificateGenerator`为Milo库的对象。 KeyPair keyPair = SelfSignedCertificateGenerator.generateRsaKeyPair(2048); // `SelfSignedCertificateBuilder`也是Milo库的对象,用来生成证书。 // 中间所设置的证书属性可以自行修改。 SelfSignedCertificateBuilder builder = new SelfSignedCertificateBuilder(keyPair) .setCommonName("Eclipse Milo Example Client") .setOrganization("digitalpetri") .setOrganizationalUnit("dev") .setLocalityName("Folsom") .setStateName("CA") .setCountryCode("US") .setApplicationUri("urn:eclipse:milo:examples:client") .addDnsName("localhost") .addIpAddress("127.0.0.1"); // Get as many hostnames and IP addresses as we can listed in the certificate. for (String hostname : HostnameUtil.getHostnames("0.0.0.0")) { if (IP_ADDR_PATTERN.matcher(hostname).matches()) { builder.addIpAddress(hostname); } else { builder.addDnsName(hostname); } } // 创建证书 X509Certificate certificate = builder.build(); // 设置对应私钥的别名,密码,证书链 keyStore.setKeyEntry(CLIENT_ALIAS, keyPair.getPrivate(), PASSWORD, new X509Certificate[]{certificate}); try (OutputStream out = Files.newOutputStream(serverKeyStore)) { // 保存证书到输出流 keyStore.store(out, PASSWORD); } } else { try (InputStream in = Files.newInputStream(serverKeyStore)) { // 如果文件存在则读取 keyStore.load(in, PASSWORD); } } // 用密码获取对应别名的私钥。 Key serverPrivateKey = keyStore.getKey(CLIENT_ALIAS, PASSWORD); if (serverPrivateKey instanceof PrivateKey) { // 获取对应别名的证书对象。 clientCertificate = (X509Certificate) keyStore.getCertificate(CLIENT_ALIAS); // 获取公钥 PublicKey serverPublicKey = clientCertificate.getPublicKey(); // 创建Keypair对象。 clientKeyPair = new KeyPair(serverPublicKey, (PrivateKey) serverPrivateKey); } return this; } // 返回证书 X509Certificate getClientCertificate() { return clientCertificate; } // 返回密钥对 KeyPair getClientKeyPair() { return clientKeyPair; }}6、业务service类
package com.jndj.platform.phase2.service.impl;import com.jndj.platform.common.milo.OpcUAClientRunner;import com.jndj.platform.common.milo.OpcUAClientService;import com.jndj.platform.phase2.service.Phase2Service;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;/** * @author yaohj * @date 2020/7/22 * 获取二期发电数据(三、四号机组) */@Service("phase2Service")public class Phase2ServiceImpl implements Phase2Service { @Autowired private OpcUAClientService opcUAClientService; /** * 获取二期发电数据(三、四号机组),保存到数据库中 */ @Override public void searchPhase2ElectricData() { new OpcUAClientRunner(opcUAClientService).run(); }}7、业务Controller类、定时调度
package com.jndj.platform.phase2.controller;import com.jndj.platform.phase2.service.Phase2Service;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.stereotype.Controller;import java.text.SimpleDateFormat;import java.util.Date;/** * @author yaohj * @date 2020/7/22 * 获取二期发电数据(三、四号机组) */@Controllerpublic class Phase2Controller { private static final Logger logger = LoggerFactory.getLogger(Phase2Controller.class); private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy:mm:dd HH:mm:ss"); @Autowired private Phase2Service phase2Service; /** * 获取二期发电数据(三、四号机组),保存到数据库中(x分钟调度一次) */ @Scheduled(initialDelay = 30000, fixedRate = 30000) public void searchGasData() { logger.info("####获取二期发电数据(三、四号机组) - 定时任务执行时间:"+ dateFormat.format(new Date())); phase2Service.searchPhase2ElectricData(); }}8、运行结果、定时获取到opcua服务中的数据
OK,以上是所有的源代码,大家的问题基本能够解决。
以上就是使用java的milo框架访问OPCUA服务的过程是怎样的,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注行业资讯频道。
服务
对象
证书
数据
客户
客户端
文件
机组
发电
别名
密码
接口
服务器
错误
运行
框架
过程
公钥
节点
安全
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
cf相同大区和服务器一样吗
京东12g数据库 黑市
西安市中学生网络安全竞赛
关系型数据库基础讲解
校园网络安全论文4000字
服务器如何提供下载库
网络安全服务模型
网络安全威胁和风险日益突出
广东企业软件开发定制
零基础怎么学好软件开发
海南节能软件开发定制
清华 狗 数据库
abp释放数据库连接池
网络安全百科
大学生网络安全文明教育
联想服务器蓝屏解决
删除服务器数据库后记录哪里能看
南充网络安全等级保护
北京银联商务软件开发笔试
网络安全法是后感
机械软件开发的课题
数据库产品公司的商业
讯腾网络技术有限公司怎么样
苏州互动安全教育展馆软件开发
代理服务器 真实ip
ajax请求多个图表数据库
关于互联网科技论文初中
使命召唤全部服务器
黄浦区口碑好的数据库服务商成本
软件开发与测试面试问题