Unity开发OPC UA客户端遇证书缺失问题及相关疑问
Unity中OPC UA Client证书找不到问题的解决及分发说明
一、解决证书找不到的错误
你遇到的ServiceResultException: ApplicationCertificate cannot be found,核心原因是代码仅配置了证书路径,但未触发OPC UA库的证书自动生成逻辑,同时Unity环境下系统环境变量不会自动解析,需要手动处理。
关键修复步骤:
- 解析系统环境变量:Unity无法自动识别
%CommonApplicationData%这类变量,需用Environment.ExpandEnvironmentVariables方法手动展开路径。 - 触发证书自动生成:OPC UA库不会主动创建证书,必须显式调用配置验证和证书初始化方法,确保证书不存在时自动生成。
二、修正后的代码示例
using System.Security.Cryptography.X509Certificates; using Opc.Ua; using Opc.Ua.Client; using System.Threading.Tasks; using UnityEngine; using System; public class OPCUAReader : MonoBehaviour { private Session session; async void Start() { var endpointUrl = "opc.tcp://opcuaserver.com:48010"; var endpoint = new ConfiguredEndpoint(null, new EndpointDescription { EndpointUrl = endpointUrl }); // 手动解析系统环境变量路径 string storePath = Environment.ExpandEnvironmentVariables(@"%%CommonApplicationData%%\OPC Foundation\CertificateStores\MachineDefault"); var config = new ApplicationConfiguration { ApplicationUri = "urn:UnityOPCClient:OPC UA Client Test", // 必须设置唯一的客户端URI ApplicationName = "OPC UA Client Test", ApplicationType = ApplicationType.Client, SecurityConfiguration = new SecurityConfiguration { ApplicationCertificate = new CertificateIdentifier { StoreType = CertificateStoreType.Directory, StorePath = storePath, SubjectName = "OPC UA Client Test", }, AutoAcceptUntrustedCertificates = true, // 允许自动信任服务器证书(测试环境可用) RejectSHA1SignedCertificates = false, MinimumCertificateKeySize = 2048 }, TransportConfigurations = new TransportConfigurationCollection(), TransportQuotas = new TransportQuotas { OperationTimeout = 60000 }, ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 } }; try { // 验证配置并触发证书生成逻辑 await config.Validate(ApplicationType.Client); // 检查证书是否存在,不存在则自动创建 var cert = config.SecurityConfiguration.ApplicationCertificate.Find(true); if (cert == null) { cert = CertificateFactory.CreateCertificate( config.SecurityConfiguration.ApplicationCertificate.StoreType, config.SecurityConfiguration.ApplicationCertificate.StorePath, null, config.ApplicationUri, config.ApplicationName, config.SecurityConfiguration.ApplicationCertificate.SubjectName, null, CertificateFactory.DefaultKeySize, DateTime.UtcNow - TimeSpan.FromDays(1), CertificateFactory.DefaultLifeTime); // 将生成的证书保存到指定路径 config.SecurityConfiguration.ApplicationCertificate.Certificate = cert; config.SecurityConfiguration.ApplicationCertificate.Save(); } // 创建OPC UA会话 session = await Session.Create( config, endpoint, true, "", 60000, null, null); await ReadVariableValue(); } catch (Exception ex) { Debug.LogError("初始化或连接失败: " + ex.Message); } } async Task ReadVariableValue() { if (session == null || !session.Connected) { Debug.LogError("会话未连接"); return; } try { var readValue = await session.ReadValueAsync(new NodeId("ns=2;s=Demo.Static.Scalar.Double")); Debug.Log("读取到的值: " + readValue.Value); } catch (Exception ex) { Debug.LogError("读取变量失败: " + ex.Message); } } private void OnDestroy() { // 销毁时关闭会话 session?.Close(); session?.Dispose(); } }
代码要点说明:
- 必须设置ApplicationUri:OPC UA协议要求每个客户端有唯一标识URI,否则证书生成会失败。
- 环境变量手动解析:确保路径在Unity环境下能正确指向证书存储目录。
- 显式证书生成逻辑:通过检查证书是否存在,触发自动创建并保存的流程。
三、分发到其他电脑的证书处理
分发后有两种可行方案:
预先打包证书:
- 在开发机上运行程序生成证书,找到
%CommonApplicationData%\OPC Foundation\CertificateStores\MachineDefault下的客户端证书文件(通常为.der和.pfx格式)。 - 将证书与程序打包,在目标电脑部署到相同路径,或者修改代码中的证书路径为程序本地目录(比如
Application.persistentDataPath),避免系统路径权限问题。
- 在开发机上运行程序生成证书,找到
目标电脑自动生成:
- 保留代码中的证书生成逻辑,首次运行时程序会自动创建证书,但需要注意:
- 目标电脑需具备对应路径的写入权限(若使用系统公共目录,可能需要以管理员身份运行程序)。
- 可将证书路径改为用户目录(比如
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)下的自定义文件夹),规避权限限制。
- 保留代码中的证书生成逻辑,首次运行时程序会自动创建证书,但需要注意:
内容的提问来源于stack exchange,提问作者Ege
相关产品推荐
相关产品推荐

