使用Digital Petri连接OPC UA Server时遇status=Bad_ConnectionClosed问题求助
解决Digital Petri OPC UA Java客户端连接时的
Bad_ConnectionClosed异常 问题背景
现有Python脚本可正常连接目标OPC UA Server:
from opcua import Client, ua opcClient = Client("opc.tcp://localhost:54321") opcClient.connect() valueNode = opcClient.get_node("ns=1;s=measure.value")
但使用Digital Petri的Java库(版本1.0.4、1.1.1)连接时,始终抛出status=Bad_ConnectionClosed异常,无论直接构建客户端还是先获取端点的方式都失败。已知服务器无证书机制、支持匿名登录。
解决方案
1. 显式配置匿名身份验证
Python客户端默认使用匿名登录,但Java库需要显式配置身份令牌。在构建OpcUaClientConfig时添加匿名身份提供者:
// 构造匿名身份令牌 AnonymousIdentityToken anonymousToken = new AnonymousIdentityToken(); IdentityProvider identityProvider = ctx -> CompletableFuture.completedFuture(anonymousToken); OpcUaClientConfig clientConfig = OpcUaClientConfig.builder() .setApplicationName(LocalizedText.english("Java OPC UA Client")) .setApplicationUri("urn:digitalpetri:java-client") .setEndpoint(endpoint) .setIdentityProvider(identityProvider) .setRequestTimeout(uint(60000)) .build();
2. 禁用证书验证(适配无证书服务器)
部分无安全策略的服务器仍会触发Java库的证书校验逻辑,需显式跳过:
// 创建接受所有证书的验证器 CertificateValidator certificateValidator = certificate -> {}; // 配置时加入验证器 OpcUaClientConfig clientConfig = OpcUaClientConfig.builder() .setApplicationName(LocalizedText.english("Java OPC UA Client")) .setApplicationUri("urn:digitalpetri:java-client") .setEndpoint(endpoint) .setCertificateValidator(certificateValidator) .setIdentityProvider(identityProvider) .setRequestTimeout(uint(60000)) .build();
3. 绕过端点发现,直接构造端点
若服务器的发现端点存在问题,可直接手动构造EndpointDescription:
// 手动构造无安全策略的端点 EndpointDescription endpoint = new EndpointDescription(); endpoint.setEndpointUrl("opc.tcp://localhost:54321"); endpoint.setSecurityPolicyUri(SecurityPolicy.None.getSecurityPolicyUri()); endpoint.setSecurityMode(MessageSecurityMode.None); endpoint.setServer(new ApplicationDescription()); // 基于手动构造的端点创建客户端配置 OpcUaClientConfig clientConfig = OpcUaClientConfig.builder() .setApplicationName(LocalizedText.english("Java OPC UA Client")) .setApplicationUri("urn:digitalpetri:java-client") .setEndpoint(endpoint) .setIdentityProvider(identityProvider) .setCertificateValidator(certificateValidator) .setRequestTimeout(uint(60000)) .build(); OpcUaClient client = new OpcUaClient(clientConfig);
4. 调整异步处理逻辑,避免阻塞调用
原代码中使用.get()阻塞线程可能导致连接超时,建议使用异步回调:
client.connect().thenCompose(conn -> { // 连接成功后读取目标节点 return client.getNode("ns=1;s=measure.value").readValue(); }).thenAccept(value -> { System.out.println("读取到的值: " + value.getValue()); }).whenComplete((value, ex) -> { if (ex != null) { System.err.println("操作失败: " + ex.getMessage()); } // 无论结果如何都关闭连接 client.disconnect(); });
5. 升级库版本
Digital Petri的1.0.4、1.1.1版本较旧,可升级到Eclipse Milo(原Digital Petri项目迁移后的官方维护版本)的最新稳定版,修复已知连接bug:
<!-- Maven依赖替换为最新Eclipse Milo版本 --> <dependency> <groupId>org.eclipse.milo</groupId> <artifactId>sdk-client</artifactId> <version>1.6.8</version> </dependency>
内容的提问来源于stack exchange,提问作者Jacob Griffin
相关产品推荐
相关产品推荐

