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