/// <summary> /// 处理保持连接心跳事件 /// </summary> private void OnKeepAliveNotification(Session session, KeepAliveEventArgs e) { try { if (e.Status != null && ServiceResult.IsNotGood(e.Status)) { IsConnected = false; if (ReconnectPeriod <= 0) { OnErrorHappened?.Invoke(this, new OpcUaErrorEventArgs((OpcUaStatusCodes)e.Status.Code, $"{ToString()},保持连接时错误", null)); return; } if (sessionReconnectHandler == null) { OnLogHappened?.Invoke(this, new OpcUaLogEventArgs($"{ToString()},重新连接中... ")); sessionReconnectHandler = new SessionReconnectHandler(); sessionReconnectHandler.BeginReconnect(session, ReconnectPeriod * 1000, Server_ReconnectComplete); } } } catch (Exception ex) { OnErrorHappened?.Invoke(this, new OpcUaErrorEventArgs(OpcUaStatusCodes.Uncertain, $"{ToString()},保持连接时发生未处理的异常", ex)); } }
/// <summary> /// 处理OPC UA服务器重连事件 /// </summary> private void Server_ReconnectComplete(object sender, EventArgs e) { try { // ignore callbacks from discarded objects. if (!Object.ReferenceEquals(sender, sessionReconnectHandler)) { OnLogHappened?.Invoke(this, new OpcUaLogEventArgs($"{ToString()},ignore callbacks from discarded objects")); return; } session = sessionReconnectHandler.Session; sessionReconnectHandler.Dispose(); sessionReconnectHandler = null; OnLogHappened(this, new OpcUaLogEventArgs($"{ToString()},重新连接成功")); IsConnected = true; } catch (Exception ex) { OnErrorHappened?.Invoke(this, new OpcUaErrorEventArgs(OpcUaStatusCodes.Uncertain, $"{ToString()},重新连接完成时发生未处理的异常", ex)); } }
/// <summary> /// 连接 /// </summary> /// <returns></returns> public async Task <OpcUaStatusCodes> ConnectAsync() { return(await Task.Run(() => { string configFilePath = System.IO.Path.Combine(AppPath ?? "", "OpcUaClient.Config.xml"); try { var certificateValidator = new CertificateValidator(); certificateValidator.CertificateValidation += OnCertificateValidatorNotification; applicationInstance = new ApplicationInstance { ApplicationType = ApplicationType.Client, ConfigSectionName = "OpcUaClient", ApplicationConfiguration = new ApplicationConfiguration { ApplicationUri = "", ApplicationName = Name, ApplicationType = ApplicationType.Client, CertificateValidator = certificateValidator, ServerConfiguration = new ServerConfiguration { MaxSubscriptionCount = 100000, MaxMessageQueueSize = 100000, MaxNotificationQueueSize = 1002, MaxPublishRequestCount = 100000 }, SecurityConfiguration = new SecurityConfiguration { AutoAcceptUntrustedCertificates = true, }, TransportQuotas = new TransportQuotas { OperationTimeout = 600000, MaxStringLength = 1048576, MaxByteStringLength = 1048576, MaxArrayLength = 65535, MaxMessageSize = 4194304, MaxBufferSize = 65535, ChannelLifetime = 600000, SecurityTokenLifetime = 3600000 }, ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000, MinSubscriptionLifetime = 10000 }, DisableHiResClock = true } }; //断开现有连接 if (session != null) { var sc = session.Close(10000); session = null; OnLogHappened?.Invoke(this, new OpcUaLogEventArgs($"{ToString()},已断开现有会话")); return OpcUaStatusCodes.Good; } applicationConfiguration = applicationInstance.ApplicationConfiguration; var selectedEndpoint = CoreClientUtils.SelectEndpoint(ServerUri, haveAppCertificate, 15000); var endpointConfiguration = EndpointConfiguration.Create(applicationConfiguration); var endpoint = new ConfiguredEndpoint(null, selectedEndpoint, endpointConfiguration); session = Session.Create(applicationConfiguration, endpoint, false, "OpcUaDeviceClient", 60000, new UserIdentity(new AnonymousIdentityToken()), null).Result; if (session == null) { OnLogHappened?.Invoke(this, new OpcUaLogEventArgs($"{ToString()},创建会话失败")); IsConnected = true; //会话初始化失败 return OpcUaStatusCodes.BadSessionIdInvalid; } else { // 保持连接句柄 session.KeepAlive += new KeepAliveEventHandler(OnKeepAliveNotification); IsConnected = true; OnLogHappened?.Invoke(this, new OpcUaLogEventArgs($"{ToString()},创建会话成功")); //连接成功后开启守护进程 daemonTimer.Enabled = true; daemonTimer.Start(); return OpcUaStatusCodes.Good; } } catch (ServiceResultException e) { OnErrorHappened?.Invoke(this, new OpcUaErrorEventArgs((OpcUaStatusCodes)e.StatusCode, $"{ToString()},连接服务器时错误", e)); return OpcUaStatusCodes.Uncertain; } catch (AggregateException ae) { StringBuilder sb = new StringBuilder(); foreach (var v in ae.InnerExceptions) { //var ex = v as ServiceResultException; sb.AppendLine(v.Message); } OnErrorHappened?.Invoke(this, new OpcUaErrorEventArgs(OpcUaStatusCodes.Uncertain, $"{ToString()},连接服务器时发生错误 {ae?.Message} {sb.ToString()}", ae)); sb.Clear(); sb = null; return OpcUaStatusCodes.Uncertain; } catch (Exception ex) { OnErrorHappened?.Invoke(this, new OpcUaErrorEventArgs(OpcUaStatusCodes.Uncertain, $"{ToString()},未处理的异常", ex)); return OpcUaStatusCodes.Uncertain; } })); }