使用java的milo框架访问OPCUA服务的过程是怎样的
发表于:2024-11-11 作者:千家信息网编辑
千家信息网最后更新 2024年11月11日,本篇文章给大家分享的是有关使用java的milo框架访问OPCUA服务的过程是怎样的,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。本次采
千家信息网最后更新 2024年11月11日使用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 PredicateendpointFilter() { 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, CompletableFuturefuture) 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 CompletableFuturefuture = 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安全错误
数据库的锁怎样保障安全
威高软件开发面试
贵州智慧党建软件开发
网吧服务器装得满吗
叶少云服务器
lol服务器离线
数据库更改多个数据
软件开发的坑 知乎
中华产业网数据库
服务器跨域
冒险岛数据库技术
sql数据库储存触发器
代理上网服务器安全问题
保定市网络安全服务人员
网络安全宣传的目的及意义
黄浦区新能源软件开发项目信息
软件开发工程师培训哪家好
虚拟专用网络技术是什么意思
南京协创互联网科技面试
华为服务器指示灯说明
明华URF-R330软件开发包
达内软件开发上海
中国网络安全国家一流学科
软件开发工具排行
cf服务器为啥不优化
包车系统软件开发公司
人生安全网络安全心得体会
淘宝买东西返钱的软件开发
数据库主从复制连接配置
烟台市检察院招聘网络技术人员
数据库的节点