【无标题】opc ua 协议 代码开发

java 复制代码
import com.sun.org.apache.xpath.internal.operations.Bool;
import lombok.extern.slf4j.Slf4j;
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.DiscoveryClient;
import org.eclipse.milo.opcua.stack.core.types.builtin.*;
import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint;

@Slf4j
@Component
public class OpcUaUtils {
    private static String endPointUrl;
    private static String username;
    private static String password;

    @Value("${relay_opc.endPointUrl}")
    public void setEndPointUrl(String endPointUrl) {
        this.endPointUrl = endPointUrl;
    }

    @Value("${relay_opc.username}")
    public void setUsername(String username) {
        this.username = username;
    }

    @Value("${relay_opc.password}")
    public void setPassword(String password) {
        this.password = password;
    }

    public static OpcUaClient createClient(String endPointUrl, String username, String password) 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);//创建OpcUA的访问证书类对象

        // 获取OPC UA的服务器端节点
        List<EndpointDescription> listEndPoints = DiscoveryClient.getEndpoints(endPointUrl).get();
        EndpointDescription endpoint = listEndPoints.get(0);

        // 设置OPC UA的配置信息
        OpcUaClientConfig config =
                OpcUaClientConfig.builder()
                        .setApplicationName(LocalizedText.english("Jisco OpcUa Client"))
                        .setApplicationUri("urn:jicso:milo:opcua:client")//放入url
                        .setCertificate(loader.getClientCertificate())//需要传入一个数字证书作为形参,我们用KeyStoreLoader类创建了
                        .setKeyPair(loader.getClientKeyPair())//传入密匙对
                        .setEndpoint(endpoint)//EndpointDescription对象,就是设置刚刚选择的节点就可以了
                        //使用匿名登录方式
                        .setIdentityProvider(new UsernameProvider(username, password))//使用用户名认证的访问验证方式
                        .setRequestTimeout(uint(5000))//设置请求超时时间,单位为毫秒。
                        .build();
        // 创建OPC UA客户端
        return OpcUaClient.create(config);
    }

    /**
     * 读取节点数据
     *
     * @param client OPC UA客户端
     * @throws Exception
     */
    public static DataValue readNode(OpcUaClient client, int namespaceIndex,
                                     String identifier) throws Exception {
        //节点
        NodeId nodeId = new NodeId(namespaceIndex, identifier);
        //读取节点数据
        return client.readValue(0.0, TimestampsToReturn.Neither, nodeId).get();
    }

    /**
     * 写入节点数据
     *
     * @param client
     * @throws Exception
     */
    public static StatusCode writeNodeValue(OpcUaClient client, int namespaceIndex,
                                            String identifier, Variant variant) throws Exception {
        //节点
        NodeId nodeId = new NodeId(namespaceIndex, identifier);
        //创建数据对象,此处的数据对象一定要定义类型,不然会出现类型错误,导致无法写入
        DataValue nowValue = new DataValue(variant, null, null);
        long begin = System.currentTimeMillis();
        //写入节点数据
        return client.writeValue(nodeId, nowValue).get();
    }


    public static int writeNodeValues(OpcUaClient client, List<NodeId> nodes, List<DataValue> values) throws Exception {

        if (nodes == null || values == null) {
            throw new NullPointerException("nodes or values is null");
        }

        if (nodes.size() != values.size()) {
            throw new IllegalArgumentException("nodeIds.size() != values.size()");
        }

        int count = nodes.size();
        CompletableFuture<List<StatusCode>> f = client.writeValues(nodes, values);
        List<StatusCode> statusCodes = f.get();
        for (int i = 0; i < statusCodes.size(); i++) {
            if (statusCodes.get(i).isBad()) {
                log.error("write '{}' to nodeId={} failed",
                        values.get(i) != null ? values.get(i).getValue().getValue().toString() : "null",
                        nodes.get(i).getIdentifier().toString());
                count--;
            }
        }
        return count;
    }

    public static int writeNodeValues(List<NodeId> nodes, List<DataValue> values) throws Exception {
        if (nodes == null || values == null) {
            throw new NullPointerException("nodes or values is null");
        }

        if (nodes.size() != values.size()) {
            throw new IllegalArgumentException("nodeIds.size() != values.size()");
        }

        //1.获取opc客户端
        OpcUaClient client = OpcUaUtils.createClient(endPointUrl, username, password);
        client.connect().get();

        int count = nodes.size();
        CompletableFuture<List<StatusCode>> f = client.writeValues(nodes, values);
        List<StatusCode> statusCodes = f.get();
        for (int i = 0; i < statusCodes.size(); i++) {
            if (statusCodes.get(i).isBad()) {
                log.error("write '{}' to nodeId={} failed",
                        values.get(i) != null ? values.get(i).getValue().getValue().toString() : "null",
                        nodes.get(i).getIdentifier().toString());
                count--;
            }
        }
        return count;
    }


    public static void main(String[] args) throws Exception {

        String endPointUrl = "opc.tcp://127.0.0.1:49320";
        OpcUaClient client = createClient(endPointUrl, "admin", "admin");
        client.connect().get();
        //StatusCode statusCode = writeNodeValue(client,2,"test03.test03.String",new Variant("abc"));
        //System.out.println(statusCode.isGood());
        //DataValue dataValue = readNode(client,2,"test03.test03.String");
        //System.out.println(dataValue.getValue().getValue().toString());

        //批量写入点位数据
        List<NodeId> nodes = new ArrayList<>();
        List<DataValue> values = new ArrayList<>();


        nodes.add(new NodeId(2, "AGvisual.stockInalertdevice.alert_time_1"));
        nodes.add(new NodeId(2, "AGvisual.stockInalertdevice.coil_no_1"));
        nodes.add(new NodeId(2, "AGvisual.stockInalertdevice.ocr_text_1"));
        nodes.add(new NodeId(2, "AGvisual.stockInalertdevice.saddle_no_1"));
        nodes.add(new NodeId(2, "AGvisual.stockInalertdevice.status_1"));
        nodes.add(new NodeId(2, "AGvisual.stockInalertdevice.track_no_1"));




//        nodes.add(new NodeId(2, "AGvisual.deviatealertdevice.alert_time"));
//        nodes.add(new NodeId(2, "AGvisual.deviatealertdevice.position"));
//        nodes.add(new NodeId(2, "AGvisual.deviatealertdevice.center_offset"));


//        values.add(new DataValue(new Variant(new Boolean(true)), null, null));
//        values.add(new DataValue(new Variant(String.valueOf("9")), null, null));
//        values.add(new DataValue(new Variant(String.valueOf("9")), null, null));
//        values.add(new DataValue(new Variant(String.valueOf("9")), null, null));
        values.add(new DataValue(new Variant(String.valueOf("20240106151601")), null, null));
        values.add(new DataValue(new Variant(String.valueOf("1025B2106")), null, null));
        values.add(new DataValue(new Variant(String.valueOf("1025B2106")), null, null));
        values.add(new DataValue(new Variant(Short.valueOf("1")), null, null));
        values.add(new DataValue(new Variant(String.valueOf("1025B2106")), null, null));
        values.add(new DataValue(new Variant(Short.valueOf("1")), null, null));
//        values.add(new DataValue(new Variant(Float.parseFloat("111")), null, null));
//        values.add(new DataValue(new Variant(Float.parseFloat("1025B2106")), null, null));
//        values.add(new DataValue(new Variant(Float.parseFloat("11")), null, null));
//        values.add(new DataValue(new Variant(Float.parseFloat("22")), null, null));
//        values.add(new DataValue(new Variant(Float.parseFloat("33")), null, null));

        int ln  = writeNodeValues(client, nodes, values);
        System.out.println("ln=" + ln);

//          for(int i=0;i<nodes.size();i++){
//              NodeId nodeId = nodes.get(i);
//              Variant variant = values.get(i).getValue();
//
//              writeNodeValue(client,2,nodeId.getIdentifier().toString(),variant);
//          }

        //批量读取点位
//        List<NodeId> nodes = new ArrayList<>();
//        nodes.add(new NodeId(2, "AGcaralarm.s_device.alarm.la_error1"));
//        nodes.add(new NodeId(2, "AGcaralarm.s_device.alarm.la_error10"));
//        List<DataValue> values = client.readValues(0.0,TimestampsToReturn.Neither,nodes).get();
//        for(DataValue dataValue : values){
//            System.out.println(dataValue.getValue().getValue().toString());
//        }

//        writeNodeValue(client,2,"AGcaralarm.alarmdevice.la_error_1-1",new Variant(false));

    }


}

创建证书对象

java 复制代码
```java


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.Arrays;
import java.util.regex.Pattern;

class KeyStoreLoader {

    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 final Logger logger = LoggerFactory.getLogger(getClass());

    private X509Certificate[] clientCertificateChain;
    private X509Certificate clientCertificate;
    private KeyPair clientKeyPair;

    KeyStoreLoader load(Path baseDir) throws Exception {
        KeyStore keyStore = KeyStore.getInstance("PKCS12");

        Path serverKeyStore = baseDir.resolve("example-client.pfx");

        logger.info("Loading KeyStore at {}", serverKeyStore);

        if (!Files.exists(serverKeyStore)) {
            keyStore.load(null, PASSWORD);

            KeyPair keyPair = SelfSignedCertificateGenerator.generateRsaKeyPair(2048);

//            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");

            SelfSignedCertificateBuilder builder = new SelfSignedCertificateBuilder(keyPair)
                    .setCommonName("Jisco OpcUa Client")
                    .setOrganization("Jisco")
                    .setOrganizationalUnit("dev")
                    .setLocalityName("Jisco")
                    .setStateName("CN")
                    .setCountryCode("ZH")
                    .setApplicationUri("urn:jicso:milo:opcua: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 clientPrivateKey = keyStore.getKey(CLIENT_ALIAS, PASSWORD);
        if (clientPrivateKey instanceof PrivateKey) {
            clientCertificate = (X509Certificate) keyStore.getCertificate(CLIENT_ALIAS);

            clientCertificateChain = Arrays.stream(keyStore.getCertificateChain(CLIENT_ALIAS))
                    .map(X509Certificate.class::cast)
                    .toArray(X509Certificate[]::new);

            PublicKey serverPublicKey = clientCertificate.getPublicKey();
            clientKeyPair = new KeyPair(serverPublicKey, (PrivateKey) clientPrivateKey);
        }

        return this;
    }

    X509Certificate getClientCertificate() {
        return clientCertificate;
    }

    public X509Certificate[] getClientCertificateChain() {
        return clientCertificateChain;
    }

    KeyPair getClientKeyPair() {
        return clientKeyPair;
    }

}
复制代码
相关推荐
阿伟*rui44 分钟前
配置管理,雪崩问题分析,sentinel的使用
java·spring boot·sentinel
XiaoLeisj3 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
paopaokaka_luck3 小时前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
dayouziei3 小时前
java的类加载机制的学习
java·学习
Yaml45 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~5 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616885 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
aloha_7895 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
记录成长java6 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
睡觉谁叫~~~6 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust