yantian yue
2023-10-17 487b2f2a353b89ab46cd9b784226b600b7b915b8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package cn.stylefeng.guns.opcua.client;
 
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.function.Predicate;
 
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.AnonymousProvider;
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.Stack;
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
 
import cn.stylefeng.guns.opcua.cert.KeyStoreLoader;
import cn.stylefeng.guns.opcua.config.Properties;
 
import lombok.extern.slf4j.Slf4j;
 
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned;
import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
/**
 * @ClassName: ClientRunner
 * @Description: 客户端启动类
 * @author yyt
 * @date 2023年10月13日
 */
@Slf4j
@Component
public class ClientRunner {
 
    private final CompletableFuture<OpcUaClient> future = new CompletableFuture<>();
 
    @Autowired
    private Properties properties;
 
    @Autowired
    private KeyStoreLoader keyStoreLoader;
 
    /**
     * @MethodName: run
     * @Description: 启动
     * @return
     * @throws Exception
     * @CreateTime 2023年10月13日
     */
    public OpcUaClient run() throws Exception {
 
        OpcUaClient client = createClient();
 
        future.whenCompleteAsync((c, ex) -> {
            if (ex != null) {
                log.error("Error running example: {}", ex.getMessage(), ex);
            }
 
            try {
                c.disconnect().get();
                Stack.releaseSharedResources();
            } catch (InterruptedException | ExecutionException e) {
                log.error("Error disconnecting:", e.getMessage(), e);
            }
        });
 
        return client;
    }
 
    /**
     * @MethodName: createClient
     * @Description: 创建客户端
     * @return
     * @throws Exception
     * @CreateTime 2023年10月13日
     */
    private OpcUaClient createClient() throws Exception {
 
        Path securityTempDir = Paths.get(properties.getCertPath(), "security");
        Files.createDirectories(securityTempDir);
        if (!Files.exists(securityTempDir)) {
            log.error("unable to create security dir: " + securityTempDir);
            return null;
        }
 
        KeyStoreLoader loader = keyStoreLoader.load(securityTempDir);
 
        // 搜索OPC节点
        List<EndpointDescription> endpoints = null;
        try {
            //获取安全策略
            endpoints = DiscoveryClient.getEndpoints(properties.getEndpointUrl()).get();
        } catch (Throwable e) {
            // try the explicit discovery endpoint as well
            String discoveryUrl = properties.getEndpointUrl();
 
            if (!discoveryUrl.endsWith("/")) {
                discoveryUrl += "/";
            }
            discoveryUrl += "discovery";
 
            log.info("Trying explicit discovery URL: {}", discoveryUrl);
            endpoints = DiscoveryClient.getEndpoints(discoveryUrl).get();
        }
 
        EndpointDescription endpoint = endpoints.stream()
                .filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getUri())).filter(endpointFilter())
                .findFirst().orElseThrow(() -> new Exception("no desired endpoints returned"));
 
        OpcUaClientConfig config = OpcUaClientConfig.builder()
                // opc ua自定义的名称
                .setApplicationName(LocalizedText.english("plc"))
                // 地址
                .setApplicationUri("opc.tcp://127.0.0.1:49320")
                .setCertificate(loader.getClientCertificate()).setKeyPair(loader.getClientKeyPair())
                // 安全策略等配置
                //.setEndpoint(endpoint).setIdentityProvider(new UsernameProvider("OPCUA", "yyt@8888888888"))
                .setEndpoint(endpoint)
                // 匿名验证
                .setIdentityProvider(new AnonymousProvider())
                //等待时间
                .setRequestTimeout(Unsigned.uint(5000)).build();
 
        return OpcUaClient.create(config);
 
    }
 
    /**
     * @MethodName: endpointFilter
     * @Description: endpointFilter
     * @return
     * @CreateTime 2023年10月13日
     */
    private Predicate<EndpointDescription> endpointFilter() {
        return e -> true;
    }
 
    /**
     * @return the future
     */
    public CompletableFuture<OpcUaClient> getFuture() {
        return future;
    }
 
}