diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2020-01-13 19:22:50 +0200 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2020-01-13 19:22:50 +0200 |
| commit | abd9951fb899fcaaba8235ec92088f16d10e3918 (patch) | |
| tree | c2782956114543cb9536d65ca82342a117686395 /Software/Visual_Studio | |
| parent | 9f3968271713394e958ba4829c11014958be44dc (diff) | |
| download | Tango-abd9951fb899fcaaba8235ec92088f16d10e3918.tar.gz Tango-abd9951fb899fcaaba8235ec92088f16d10e3918.zip | |
Working on external bridge v2
Diffstat (limited to 'Software/Visual_Studio')
10 files changed, 479 insertions, 655 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs index 161a8cca7..e51247337 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs @@ -147,6 +147,13 @@ namespace Tango.MachineStudio.UI } catch { } + if (e.Exception.ToString().Contains("A Task's exception(s) were not observed")) + { + e.TryRecover = true; + LogManager.Log("Task not observed exception. Ignoring..."); + return; + } + try { var eventLogger = TangoIOC.Default.GetInstance<IEventLogger>(); diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/DefaultMachineProvider.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/DefaultMachineProvider.cs index 6d90ece73..9b818bd9d 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/DefaultMachineProvider.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/DefaultMachineProvider.cs @@ -81,7 +81,7 @@ namespace Tango.PPC.Common.Connection MachineOperator.EnableJobResume = true; MachineOperator.UseKeepAlive = true; MachineOperator.EnableMachineStatusUpdates = true; - MachineOperator.EnableDiagnostics = false; + MachineOperator.EnableDiagnostics = true; MachineOperator.EnableEmbeddedDebugging = settings.EnableEmbeddedDebugLogs; MachineOperator.EnableAutomaticThreadLoading = settings.EnableAutomaticThreadLoading; diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/App.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/App.xaml.cs index ebe68a5d3..fd0e288c8 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/App.xaml.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/App.xaml.cs @@ -111,6 +111,12 @@ namespace Tango.PPC.UI return; } + if (e.Exception.ToString().Contains("A Task's exception(s) were not observed")) + { + LogManager.Log("Task not observed exception. Ignoring..."); + return; + } + try { LogManager.Log(e.Exception, "Application Crashed!"); diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs index 057ff91d3..c43598746 100644 --- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs +++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs @@ -1,17 +1,20 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Net.Sockets; using System.Security.Authentication; using System.Text; using System.Threading.Tasks; using Tango.Core.ExtensionMethods; +using Tango.Integration.Operation; using Tango.PMR; using Tango.PMR.Common; using Tango.PMR.Debugging; using Tango.PMR.Diagnostics; using Tango.PMR.Integration; using Tango.PMR.MachineStatus; +using Tango.PMR.Power; using Tango.Transport; using Tango.Transport.Adapters; using Tango.Transport.Transporters; @@ -20,6 +23,8 @@ namespace Tango.Integration.ExternalBridge { public class ExternalBridgeReceiver : BasicTransporter { + #region Message Handler + private class MessageHandler { public Action<MessageContainer> Method { get; set; } @@ -38,97 +43,196 @@ namespace Tango.Integration.ExternalBridge } } + #endregion + private String _eventsToken; private String _machineStatusToken; private String _diagnosticsToken; private String _debugLogsToken; + private String _applicationLogsToken; + private IMachineOperator _machineOperator; private Dictionary<MessageType, MessageHandler> _messageHandlers; + #region Events + public event EventHandler<ExternalBridgeReceiverLoginRequestEventArgs> LoginRequest; + public event EventHandler<ColorProfileRequestEventArgs> ColorProfileRequest; + public event EventHandler Disconnected; + + #endregion + + #region Properties public bool RequiresDiagnostics { get; private set; } public bool RequiresDebugLogs { get; private set; } public bool RequiresEventsNotification { get; private set; } public bool RequiresMachineStatusUpdate { get; private set; } + public bool RequiresApplicationLogs { get; set; } public bool IsLoggedIn { get; private set; } public ExternalBridgeLoginIntent LoginIntent { get; private set; } - public ExternalBridgeReceiver() + public bool IsLoggedInAndRequiresDiagnostics + { + get { return IsLoggedIn && (LoginIntent == ExternalBridgeLoginIntent.Diagnostics || LoginIntent == ExternalBridgeLoginIntent.FullControl); } + } + + + #endregion + + #region Constructors + + public ExternalBridgeReceiver(IMachineOperator machineOperator) { + ComponentName = "External Bridge Receiver"; + + _machineOperator = machineOperator; + _messageHandlers = new Dictionary<MessageType, MessageHandler>(); UseKeepAlive = false; KeepAliveTimeout = TimeSpan.FromSeconds(5); KeepAliveRetries = 2; - _messageHandlers.Add(MessageType.ExternalBridgeLoginRequest, new MessageHandler(OnLoginRequest)); + _messageHandlers.Add(MessageType.ExternalBridgeLoginRequest, new MessageHandler(OnExternalBridgeLoginRequest)); + _messageHandlers.Add(MessageType.ExternalBridgeLogoutRequest, new MessageHandler(OnExternalBridgeLogoutRequest)); + + _messageHandlers.Add(MessageType.ColorProfileRequest, new MessageHandler(OnColorProfileRequest)); + + _messageHandlers.Add(MessageType.StartDiagnosticsRequest, new MessageHandler(OnStartDiagnosticsRequest, ExternalBridgeLoginIntent.Diagnostics)); + _messageHandlers.Add(MessageType.StopDiagnosticsRequest, new MessageHandler(OnStopDiagnosticsRequest, ExternalBridgeLoginIntent.Diagnostics)); + + _messageHandlers.Add(MessageType.StartDebugLogRequest, new MessageHandler(OnStartDebugLogRequest, ExternalBridgeLoginIntent.Diagnostics)); + _messageHandlers.Add(MessageType.StopDebugLogRequest, new MessageHandler(OnStopDebugLogRequest, ExternalBridgeLoginIntent.Diagnostics)); + + _messageHandlers.Add(MessageType.StartEventsNotificationRequest, new MessageHandler(OnStartEventsNotificationRequest, ExternalBridgeLoginIntent.Diagnostics)); + _messageHandlers.Add(MessageType.StopEventsNotificationRequest, new MessageHandler(OnStopEventsNotificationRequest, ExternalBridgeLoginIntent.Diagnostics)); - _messageHandlers.Add(MessageType.StartDiagnosticsRequest, new MessageHandler(OnStartDiagnosticsRequest, ExternalBridgeLoginIntent.Diagnostics | ExternalBridgeLoginIntent.FullControl)); - _messageHandlers.Add(MessageType.StopDiagnosticsRequest, new MessageHandler(OnStopDiagnosticsRequest, ExternalBridgeLoginIntent.Diagnostics | ExternalBridgeLoginIntent.FullControl)); + _messageHandlers.Add(MessageType.StartMachineStatusUpdateRequest, new MessageHandler(OnStartMachineStatusUpdateRequest, ExternalBridgeLoginIntent.Diagnostics)); + _messageHandlers.Add(MessageType.StopMachineStatusUpdateRequest, new MessageHandler(OnStopMachineStatusUpdateRequest, ExternalBridgeLoginIntent.Diagnostics)); - _messageHandlers.Add(MessageType.StartDebugLogRequest, new MessageHandler(OnStartDebugLogRequest, ExternalBridgeLoginIntent.Diagnostics | ExternalBridgeLoginIntent.FullControl)); - _messageHandlers.Add(MessageType.StopDebugLogRequest, new MessageHandler(OnStopDebugLogRequest, ExternalBridgeLoginIntent.Diagnostics | ExternalBridgeLoginIntent.FullControl)); + _messageHandlers.Add(MessageType.StartApplicationLogsRequest, new MessageHandler(OnStartApplicationLogsRequest, ExternalBridgeLoginIntent.Diagnostics)); + _messageHandlers.Add(MessageType.StopApplicationLogsRequest, new MessageHandler(OnStopApplicationLogsRequest, ExternalBridgeLoginIntent.Diagnostics)); - _messageHandlers.Add(MessageType.StartEventsNotificationRequest, new MessageHandler(OnStartEventsNotificationRequest, ExternalBridgeLoginIntent.Diagnostics | ExternalBridgeLoginIntent.FullControl)); - _messageHandlers.Add(MessageType.StopEventsNotificationRequest, new MessageHandler(OnStopEventsNotificationRequest, ExternalBridgeLoginIntent.Diagnostics | ExternalBridgeLoginIntent.FullControl)); + _messageHandlers.Add(MessageType.JobRequest, new MessageHandler(OnJobRequest, ExternalBridgeLoginIntent.Diagnostics)); - _messageHandlers.Add(MessageType.StartMachineStatusUpdateRequest, new MessageHandler(OnStartMachineStatusUpdateRequest, ExternalBridgeLoginIntent.Diagnostics | ExternalBridgeLoginIntent.FullControl)); - _messageHandlers.Add(MessageType.StopMachineStatusUpdateRequest, new MessageHandler(OnStopMachineStatusUpdateRequest, ExternalBridgeLoginIntent.Diagnostics | ExternalBridgeLoginIntent.FullControl)); + _messageHandlers.Add(MessageType.StartPowerDownRequest, new MessageHandler(OnStartPowerDownRequest, ExternalBridgeLoginIntent.Diagnostics)); } - public ExternalBridgeReceiver(TcpClient tcpClient) : this() + public ExternalBridgeReceiver(TcpClient tcpClient, IMachineOperator machineOperator) : this(machineOperator) { Adapter = new TcpTransportAdapter(tcpClient); } + #endregion + + #region Override Methods + protected override void OnRequestReceived(MessageContainer container) { base.OnRequestReceived(container); - if (_messageHandlers.ContainsKey(container.Type)) + try { - var handler = _messageHandlers[container.Type]; - - if (handler.RequiresLogin && (!IsLoggedIn || !LoginIntent.HasFlag(handler.LoginIntent))) + if (_messageHandlers.ContainsKey(container.Type)) { - SendErrorResponse(new AuthenticationException("The specified intent does not grant the specified action."), container.Token); - return; - } + var handler = _messageHandlers[container.Type]; + + if (handler.RequiresLogin && (!IsLoggedIn || (int)handler.LoginIntent > (int)LoginIntent)) + { + SendErrorResponse(new AuthenticationException("The specified intent does not grant the specified action."), container.Token); + return; + } - try - { try { - handler.Method.Invoke(container); + try + { + handler.Method.Invoke(container); + } + catch (Exception ex) + { + SendErrorResponse(ex, container.Token); + } } catch (Exception ex) { - SendErrorResponse(ex, container.Token); + if (ex is ResponseErrorException) + { + SendResponse((ex as ResponseErrorException).Container); + } + else + { + SendErrorResponse(ex, container.Token); + } } } - catch (Exception ex) + else { - if (ex is ResponseErrorException) + if (IsLoggedIn) { - SendResponse((ex as ResponseErrorException).Container); - } - else - { - SendErrorResponse(ex, container.Token); + OnAnyRequest(container); } } } - else + catch (Exception ex) { - - OnAnyRequest(container); + LogManager.Log(ex, "Error occurred in processing request message on external bridge receiver."); + } + } + + protected override void OnFailed(Exception ex) + { + if (ex is KeepAliveException) + { + LogManager.Log("External bridge client has failed to provide a keep alive response. Disconnecting session..."); } + + base.OnFailed(ex); } + public async override Task Disconnect() + { + try + { + if (IsLoggedIn) + { + await SendRequest<ExternalBridgeLogoutRequest, ExternalBridgeLogoutResponse>(new ExternalBridgeLogoutRequest(), TimeSpan.FromSeconds(0.5)); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error sending an external bridge log out request."); + } + finally + { + ClearQueues(); + } + + try + { + IsLoggedIn = false; + await base.Disconnect(); + } + catch { } + + OnDisconnected(); + } + + #endregion + + #region Virtual Methods + + protected virtual void OnDisconnected() + { + Disconnected?.Invoke(this, new EventArgs()); + } + + #endregion + #region Message Handlers - protected virtual void OnLoginRequest(MessageContainer container) + protected virtual void OnExternalBridgeLoginRequest(MessageContainer container) { var request = MessageFactory.ParseTangoMessageFromContainer<ExternalBridgeLoginRequest>(container); @@ -148,33 +252,50 @@ namespace Tango.Integration.ExternalBridge response.DeviceInformation = deviceInfo; SendResponse<ExternalBridgeLoginResponse>(response, container.Token); + + UpdateMachineOperatorStatus((UpdateStatus)_machineOperator.Status); + + UseKeepAlive = true; }, - (reason) => + (reason) => { //Decline SendResponse<ExternalBridgeLoginResponse>(new ExternalBridgeLoginResponse(), container.Token, false, ErrorCode.GeneralError, reason); + Disconnect().GetAwaiter().GetResult(); }); + + args.IpAddress = Adapter.Address; + args.Request = request; + + LoginRequest?.Invoke(this, args); } - private void OnAnyRequest(MessageContainer container) + protected virtual void OnExternalBridgeLogoutRequest(MessageContainer container) { - if (SessionIntent == ExternalBridgeLoginIntent.ColorProfile) + try + { + SendResponse<ExternalBridgeLogoutResponse>(new ExternalBridgeLogoutResponse(), container.Token); + } + catch (Exception ex) { - await SendErrorResponse(new AuthenticationException("The specified intent does not grant the specified action."), container.Token); - return; + LogManager.Log(ex); } + finally + { + OnDisconnected(); + ClearQueues(); + } + } + protected async virtual void OnAnyRequest(MessageContainer container) + { if (!container.Continuous) { try { - var response = await MachineOperator.SendRequest(container); + var response = await _machineOperator.SendRequest(container); await SendResponse(response); } - //catch (TimeoutException) - //{ - - //} catch (Exception ex) { await SendErrorResponse(ex, container.Token); @@ -184,16 +305,16 @@ namespace Tango.Integration.ExternalBridge { try { - MachineOperator.SendContinuousRequest(container).Subscribe((response) => + _machineOperator.SendContinuousRequest(container).Subscribe((response) => { - if (Enabled && IsInSession) + if (State == TransportComponentState.Connected) { SendResponse(response); } }, (ex) => { - if (Enabled) + if (State == TransportComponentState.Connected) { if (ex is ResponseErrorException) { @@ -209,6 +330,31 @@ namespace Tango.Integration.ExternalBridge } } + protected virtual void OnColorProfileRequest(MessageContainer container) + { + var request = MessageFactory.ParseTangoMessageFromContainer<ColorProfileRequest>(container); + + ColorProfileRequestEventArgs e = new ColorProfileRequestEventArgs(request, async () => + { + //Approved. + await SendResponse<ColorProfileResponse>(new ColorProfileResponse() + { + Approved = true + }, container.Token); + await Task.Delay(500); + await base.Disconnect(); + }, + async () => + { + //Declined. + await SendResponse<ColorProfileResponse>(new ColorProfileResponse(), container.Token); + await Task.Delay(500); + await base.Disconnect(); + }); + + ColorProfileRequest?.Invoke(this, e); + } + protected virtual void OnStartDiagnosticsRequest(MessageContainer container) { _diagnosticsToken = container.Token; @@ -281,38 +427,149 @@ namespace Tango.Integration.ExternalBridge } } + protected virtual void OnStartApplicationLogsRequest(MessageContainer container) + { + _applicationLogsToken = container.Token; + SendResponse<StartApplicationLogsResponse>(new StartApplicationLogsResponse(), _applicationLogsToken); + RequiresApplicationLogs = true; + } + + protected virtual void OnStopApplicationLogsRequest(MessageContainer container) + { + if (_applicationLogsToken != null) + { + RequiresApplicationLogs = false; + SendResponse<StartApplicationLogsResponse>(new StartApplicationLogsResponse(), _applicationLogsToken, true); + _applicationLogsToken = null; + SendResponse<StopApplicationLogsResponse>(new StopApplicationLogsResponse(), container.Token); + } + } + + protected virtual void OnJobRequest(MessageContainer container) + { + if (LoginIntent != ExternalBridgeLoginIntent.FullControl) + { + throw new InvalidOperationException($"Job execution is disabled while session intent is '{LoginIntent}'."); + } + if (_machineOperator.IsPrinting) + { + throw new InvalidOperationException($"Could not execute job while machine operator status is '{_machineOperator.Status}'."); + } + else + { + OnAnyRequest(container); + } + } + + protected virtual void OnStartPowerDownRequest(MessageContainer container) + { + SendResponse(new StartPowerDownResponse() { }, container.Token, false, ErrorCode.ContinuousResponseAborted, "Power down request is not supported via external bridge."); + } + #endregion - public void UpdateDiagnostics(StartDiagnosticsResponse response) + #region Continuous Updates + + public void UpdateDiagnostics(MessageContainer container) { - if (_diagnosticsToken != null) + try { - SendResponse<StartDiagnosticsResponse>(response, _diagnosticsToken); + if (_diagnosticsToken != null) + { + var cloned = container.Clone(); + cloned.Token = _diagnosticsToken; + SendResponse(cloned); + } + } + catch (Exception ex) + { + Debug.WriteLine(ex); } } - public void UpdateDebugLogs(StartDebugLogResponse response) + public void UpdateDebugLogs(MessageContainer container) { - if (_debugLogsToken != null) + try { - SendResponse<StartDebugLogResponse>(response, _debugLogsToken); + if (_debugLogsToken != null) + { + var cloned = container.Clone(); + cloned.Token = _debugLogsToken; + SendResponse(cloned); + } + } + catch (Exception ex) + { + Debug.WriteLine(ex); } } - public void UpdateEvents(StartEventsNotificationResponse response) + public void UpdateEvents(MessageContainer container) { - if (_eventsToken != null) + try { - SendResponse<StartEventsNotificationResponse>(response, _eventsToken); + if (_eventsToken != null) + { + var cloned = container.Clone(); + cloned.Token = _eventsToken; + SendResponse(cloned); + } + } + catch (Exception ex) + { + Debug.WriteLine(ex); } } - public void UpdateMachineStatus(StartMachineStatusUpdateResponse response) + public void UpdateMachineStatus(MessageContainer container) { - if (_machineStatusToken != null) + try + { + if (_machineStatusToken != null) + { + var cloned = container.Clone(); + cloned.Token = _machineStatusToken; + SendResponse(cloned); + } + } + catch (Exception ex) { - SendResponse<StartMachineStatusUpdateResponse>(response, _machineStatusToken); + Debug.WriteLine(ex); } } + + public void UpdateApplicationLogs(MessageContainer container) + { + try + { + if (_applicationLogsToken != null) + { + var cloned = container.Clone(); + cloned.Token = _applicationLogsToken; + SendResponse(cloned); + } + } + catch (Exception ex) + { + Debug.WriteLine(ex); + } + } + + public void UpdateMachineOperatorStatus(UpdateStatus status) + { + try + { + SendRequest<UpdateStatusRequest, UpdateStatusResponse>(new UpdateStatusRequest() + { + Status = status, + }); + } + catch (Exception ex) + { + Debug.WriteLine(ex); + } + } + + #endregion } } diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs index e20b12d1a..d365de5c6 100644 --- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs +++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs @@ -74,7 +74,9 @@ namespace Tango.Integration.ExternalBridge if (_server == null) { - _server = new UdpClient(_settings.ExternalBridgeServiceDiscoveryPort); + _server = new UdpClient(); + _server.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + _server.Client.Bind(new IPEndPoint(IPAddress.Any, _settings.ExternalBridgeServiceDiscoveryPort)); } IsStarted = true; diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs index c4cca10f1..a0f81c835 100644 --- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs +++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs @@ -31,16 +31,8 @@ namespace Tango.Integration.ExternalBridge private List<ExternalBridgeReceiver> _receivers; private UdpDiscoveryService<ExternalBridgeUdpDiscoveryPacket> _discoveryService; private TcpServer _tcpServer; - private bool _send_app_logs; - private String _app_logs_token; - private Dictionary<MessageType, Action<MessageContainer>> _messageHandlers; private int _discovery_port = 8888; //Will be overridden by settings in constructor.. private int _external_bridge_port = 1984; //Will be overridden by settings in constructor.. - private String _eventsNotificationsToken; - private String _machineStatusUpdateToken; - private String _diagnosticsNotificationToken; - private String _debugLogsNotificationToken; - private bool _resend_diagnostics; #region Events @@ -143,9 +135,6 @@ namespace Tango.Integration.ExternalBridge _discovery_port = settings.ExternalBridgeServiceDiscoveryPort; _external_bridge_port = settings.ExternalBridgeServicePort; - _messageHandlers = new Dictionary<MessageType, Action<MessageContainer>>(); - RegisterMessageHandlers(); - _tcpServer = new TcpServer(_external_bridge_port); _tcpServer.ClientConnected += _tcpServer_ClientConnected; @@ -198,8 +187,6 @@ namespace Tango.Integration.ExternalBridge { if (MachineOperator != null) { - MachineOperator.StateChanged -= MachineOperator_StateChanged; - MachineOperator.StateChanged += MachineOperator_StateChanged; MachineOperator.StatusChanged -= MachineOperator_StatusChanged; MachineOperator.StatusChanged += MachineOperator_StatusChanged; MachineOperator.PendingResponseReceived -= MachineOperator_PendingResponseReceived; @@ -218,159 +205,102 @@ namespace Tango.Integration.ExternalBridge /// <param name="e">The <see cref="ClientConnectedEventArgs"/> instance containing the event data.</param> private async void _tcpServer_ClientConnected(object sender, ClientConnectedEventArgs e) { - if (!IsInSession) + LogManager.Log("External bridge client connected from: " + e.Socket.GetIPAddress()); + ExternalBridgeReceiver receiver = new ExternalBridgeReceiver(e.Socket, MachineOperator); + receiver.LoginRequest += Receiver_LoginRequest; + receiver.ColorProfileRequest += Receiver_ColorProfileRequest; + receiver.Disconnected += Receiver_Disconnected; + _receivers.Add(receiver); + await receiver.Connect(); + } + + private void MachineOperator_StatusChanged(object sender, MachineStatuses status) + { + try { - LogManager.Log("External bridge client connected from: " + e.Socket.GetIPAddress()); - ExternalBridgeReceiver receiver = new ExternalBridgeReceiver(e.Socket); - receiver.RequestReceived += Receiver_RequestReceived; - _receivers.Add(receiver); - await receiver.Connect(); + _receivers.ToList().Where(x => x.IsLoggedInAndRequiresDiagnostics).ToList().ForEach(x => x.UpdateMachineOperatorStatus((UpdateStatus)status)); } - else + catch (Exception ex) { - e.Socket.Dispose(); + LogManager.Log(ex, "Error updating status of external bridge service client."); } } - private void Receiver_RequestReceived(object sender, MessageContainer container) + private void LogManager_NewLog(object sender, Tango.Logging.LogItemBase e) { - ExternalBridgeReceiver receiver = sender as ExternalBridgeReceiver; + var toSend = _receivers.ToList().Where(x => x.IsLoggedInAndRequiresDiagnostics && x.RequiresApplicationLogs).ToList(); - try + if (_receivers.Count > 0) { - if (Enabled) + var msg = MessageFactory.CreateTangoMessage<StartApplicationLogsResponse>(new StartApplicationLogsResponse() { - if (container.Type == MessageType.ConnectRequest || container.Type == MessageType.DisconnectRequest) - { - //Do nothing ! - } - else - { - if (IsInSession) - { - if (container.Type == MessageType.ExternalBridgeLoginRequest) - { - receiver.SendErrorResponse(new AuthenticationException("Machine is already in session."), container.Token); - return; - } + LogItem = ByteString.CopyFrom(e.Serialize()) + }); - if (_messageHandlers.ContainsKey(container.Type)) - { - try - { - try - { - _messageHandlers[container.Type](container); - } - catch (Exception ex) - { - receiver.SendErrorResponse(ex, container.Token); - } - } - catch (Exception ex) - { - if (ex is ResponseErrorException) - { - receiver.SendResponse((ex as ResponseErrorException).Container); - } - else - { - receiver.SendErrorResponse(ex, container.Token); - } - } - } - else - { - OnAnyRequest(container); - } - } - else - { - if (container.Type == MessageType.ExternalBridgeLoginRequest) - { - OnExternalBridgeLoginRequest(container); - } - else if (container.Type == MessageType.ColorProfileRequest) - { - OnColorProfileRequest(container); - } - } - } - } - } - catch (Exception ex) - { - LogManager.Log(ex, String.Format("An error occurred while processing a request message '{0}' from the remote host.", container.Type)); + msg.ToBytes(); + + toSend.ToList().ForEach(x => x.UpdateApplicationLogs(msg.Container)); } } - /// <summary> - /// Machines the operator state changed. - /// </summary> - /// <param name="sender">The sender.</param> - /// <param name="e">The e.</param> - private void MachineOperator_StateChanged(object sender, TransportComponentState e) + private void MachineOperator_PendingResponseReceived(object sender, MessageContainer container) { - //Do nothing right now. - if (e != TransportComponentState.Connected) + OnOperatorResponseReceived(container); + } + + #endregion + + #region Receiver Events Handlers + + private void Receiver_Disconnected(object sender, EventArgs e) + { + var receiver = sender as ExternalBridgeReceiver; + _receivers.Remove(receiver); + if (receiver.LoginIntent == ExternalBridgeLoginIntent.FullControl) { - _resend_diagnostics = true; + ClientDisconnected?.Invoke(this, new EventArgs()); } } - private async void MachineOperator_StatusChanged(object sender, MachineStatuses e) + private void Receiver_ColorProfileRequest(object sender, ColorProfileRequestEventArgs e) { - if (e == MachineStatuses.ReadyToDye && _machineOperator.State == TransportComponentState.Connected) - { - if (IsInSession && _resend_diagnostics) - { - _resend_diagnostics = false; + ColorProfileRequest?.Invoke(this, e); + } - if (_diagnosticsNotificationToken != null) - { - var msg = MessageFactory.CreateTangoMessage<StartDiagnosticsRequest>(_diagnosticsNotificationToken); - _machineOperator.SendContinuousRequest<StartDiagnosticsRequest, StartDiagnosticsResponse>(msg); - } - } - } + private void Receiver_LoginRequest(object sender, ExternalBridgeReceiverLoginRequestEventArgs e) + { + var request = e.Request; - if (IsInSession) + if (request.Intent == ExternalBridgeLoginIntent.FullControl && _receivers.Any(x => x.IsLoggedIn && x.LoginIntent == ExternalBridgeLoginIntent.FullControl)) { - try - { - UpdateStatus s = (UpdateStatus)e; - - await SendRequest<UpdateStatusRequest, UpdateStatusResponse>(new UpdateStatusRequest() - { - Status = s, - }); - } - catch (Exception ex) - { - LogManager.Log(ex, "Error updating status of external bridge service client."); - } + e.Decline("Only one full control client is allowed."); + return; } - } - private void LogManager_NewLog(object sender, Tango.Logging.LogItemBase e) - { - if (State == TransportComponentState.Connected && _send_app_logs) + if (request.Intent == ExternalBridgeLoginIntent.FullControl && MachineOperator.IsPrinting) { - try - { - SendResponse<StartApplicationLogsResponse>(new StartApplicationLogsResponse() - { - LogItem = ByteString.CopyFrom(e.Serialize()) - }, _app_logs_token); - } - catch { } + e.Decline($"External bridge client login failed because the machine is currently printing and '{ExternalBridgeLoginIntent.FullControl}' intent was requested."); + return; } - } + ExternalBridgeClientConnectedEventArgs args = new ExternalBridgeClientConnectedEventArgs(); + args.Request = request; + args.IpAddress = e.IpAddress; + ConnectionRequest?.Invoke(this, args); - private void MachineOperator_PendingResponseReceived(object sender, MessageContainer container) - { - OnOperatorResponseReceived(container); + var response = new ExternalBridgeLoginResponse(); + response.Authenticated = args.Confirmed; + response.SerialNumber = Machine.SerialNumber; + response.DeviceInformation = MachineOperator.DeviceInformation; + + if (args.Confirmed) + { + e.Confirm(Machine, MachineOperator.DeviceInformation); + } + else + { + e.Decline("Invalid password or intent."); + } } #endregion @@ -403,16 +333,15 @@ namespace Tango.Integration.ExternalBridge _tcpServer.Stop(); _discoveryService.Stop(); + foreach (var receiver in _receivers.ToList()) + { + await receiver.Disconnect(); + } + IsStarted = false; IsInSession = false; _enabled = false; RaisePropertyChanged(nameof(Enabled)); - - try - { - await Disconnect(); - } - catch { } } } @@ -421,411 +350,39 @@ namespace Tango.Integration.ExternalBridge /// </summary> public async void DisconnectSession() { - await Disconnect(); - } - - #endregion - - #region Override Methods - - public async override Task Disconnect() - { - _send_app_logs = false; - - try + var sessionReceiver = _receivers.SingleOrDefault(x => x.IsLoggedIn && x.LoginIntent == ExternalBridgeLoginIntent.FullControl); + if (sessionReceiver != null) { - if (IsInSession) - { - await SendRequest<ExternalBridgeLogoutRequest, ExternalBridgeLogoutResponse>(new ExternalBridgeLogoutRequest(), TimeSpan.FromSeconds(0.5)); - } - } - catch (Exception ex) - { - LogManager.Log(ex, "Error sending an external bridge log out request."); + await sessionReceiver.Disconnect(); } - finally - { - ClearQueues(); - } - - OnClientDisconnected(); } - protected override void OnFailed(Exception ex) - { - if (ex is KeepAliveException) - { - LogManager.Log("External bridge client has failed to provide a keep alive response. Disconnecting session..."); - } - - base.OnFailed(ex); - } #endregion #region Virtual Methods - protected async virtual void OnClientDisconnected() - { - _eventsNotificationsToken = null; - _machineStatusUpdateToken = null; - _diagnosticsNotificationToken = null; - _debugLogsNotificationToken = null; - IsInSession = false; - _send_app_logs = false; - - if (MachineOperator.State == TransportComponentState.Connected) - { - try - { - await MachineOperator.SendRequest(new StopDiagnosticsRequest()); - } - catch (Exception ex) - { - LogManager.Log(ex); - } - } - - ClientDisconnected?.Invoke(this, new EventArgs()); - - try - { - await base.Disconnect(); - } - catch (Exception ex) - { - LogManager.Log(ex); - } - - LogManager.Log("External bridge client disconnected."); - } - protected virtual void OnOperatorResponseReceived(MessageContainer container) { try { - if (IsInSession) + switch (container.Type) { - if (container.Type == MessageType.StartEventsNotificationResponse) - { - if (_eventsNotificationsToken != null) - { - container.Token = _eventsNotificationsToken; - SendResponse(container); - } - } - if (container.Type == MessageType.StartMachineStatusUpdateResponse) - { - if (_machineStatusUpdateToken != null) - { - container.Token = _machineStatusUpdateToken; - SendResponse(container); - } - } - else if (container.Type == MessageType.StartDiagnosticsResponse) - { - if (_diagnosticsNotificationToken != null) - { - container.Token = _diagnosticsNotificationToken; - SendResponse(container); - } - } - else if (container.Type == MessageType.StartDebugLogResponse) - { - if (_debugLogsNotificationToken != null) - { - container.Token = _debugLogsNotificationToken; - SendResponse(container); - } - } + case MessageType.StartDiagnosticsResponse: + _receivers.ToList().Where(x => x.IsLoggedInAndRequiresDiagnostics && x.RequiresDiagnostics).ToList().ForEach(x => x.UpdateDiagnostics(container)); + break; + case MessageType.StartDebugLogResponse: + _receivers.ToList().Where(x => x.IsLoggedInAndRequiresDiagnostics && x.RequiresDebugLogs).ToList().ForEach(x => x.UpdateDebugLogs(container)); + break; + case MessageType.StartEventsNotificationResponse: + _receivers.ToList().Where(x => x.IsLoggedInAndRequiresDiagnostics && x.RequiresEventsNotification).ToList().ForEach(x => x.UpdateEvents(container)); + break; + case MessageType.StartMachineStatusUpdateResponse: + _receivers.ToList().Where(x => x.IsLoggedInAndRequiresDiagnostics && x.RequiresMachineStatusUpdate).ToList().ForEach(x => x.UpdateMachineStatus(container)); + break; } - } - catch { } - } - - #endregion - - #region Message Handlers - private void RegisterMessageHandlers() - { - _messageHandlers.Add(MessageType.ExternalBridgeLogoutRequest, OnExternalBridgeLogoutRequest); - - _messageHandlers.Add(MessageType.StartApplicationLogsRequest, OnStartApplicationLogsRequest); - _messageHandlers.Add(MessageType.StopApplicationLogsRequest, OnStopApplicationLogsRequest); - - _messageHandlers.Add(MessageType.JobRequest, OnJobRequest); - - //Events - _messageHandlers.Add(MessageType.StartEventsNotificationRequest, OnStartEventsNotificationRequest); - _messageHandlers.Add(MessageType.StopEventsNotificationRequest, OnStopEventsNotificationRequest); - - //Machine Status - _messageHandlers.Add(MessageType.StartMachineStatusUpdateRequest, OnStartMachineStatusUpdateRequest); - _messageHandlers.Add(MessageType.StopMachineStatusUpdateRequest, OnStopMachineStatusUpdateRequest); - - //Diagnostics - _messageHandlers.Add(MessageType.StartDiagnosticsRequest, OnStartDiagnosticsRequest); - _messageHandlers.Add(MessageType.StopDiagnosticsRequest, OnStopDiagnosticsRequest); - - //Debug Logs - _messageHandlers.Add(MessageType.StartDebugLogRequest, OnStartDebugLogRequest); - _messageHandlers.Add(MessageType.StopDebugLogRequest, OnStopDebugLogRequest); - - //Start Power Down - _messageHandlers.Add(MessageType.StartPowerDownRequest, OnStartPowerDownRequest); - } - - protected virtual async void OnAnyRequest(MessageContainer container) - { - if (SessionIntent == ExternalBridgeLoginIntent.ColorProfile) - { - await SendErrorResponse(new AuthenticationException("The specified intent does not grant the specified action."), container.Token); - return; } - - if (!container.Continuous) - { - try - { - var response = await MachineOperator.SendRequest(container); - await SendResponse(response); - } - //catch (TimeoutException) - //{ - - //} - catch (Exception ex) - { - await SendErrorResponse(ex, container.Token); - } - } - else - { - try - { - MachineOperator.SendContinuousRequest(container).Subscribe((response) => - { - if (Enabled && IsInSession) - { - SendResponse(response); - } - - }, (ex) => - { - if (Enabled) - { - if (ex is ResponseErrorException) - { - SendResponse((ex as ResponseErrorException).Container); - } - } - }); - } - catch (Exception ex) - { - await SendErrorResponse(ex, container.Token); - } - } - } - - protected async virtual void OnExternalBridgeLoginRequest(MessageContainer container) - { - var request = MessageFactory.ParseTangoMessageFromContainer<ExternalBridgeLoginRequest>(container); - - LogManager.Log($"External bridge login attempt:\nIntent: {request.Message.Intent}\nMessage:\n{request.Message.ToJsonString()}"); - - if (MachineOperator.Status != MachineStatuses.Printing || request.Message.Intent != ExternalBridgeLoginIntent.FullControl) - { - ExternalBridgeClientConnectedEventArgs args = new ExternalBridgeClientConnectedEventArgs(); - args.Request = request; - args.IpAddress = Adapter.Address; - ConnectionRequest?.Invoke(this, args); - - var response = new ExternalBridgeLoginResponse(); - response.Authenticated = args.Confirmed; - response.SerialNumber = Machine.SerialNumber; - response.DeviceInformation = MachineOperator.DeviceInformation; - - IsInSession = args.Confirmed; - - if (IsInSession) - { - LogManager.Log("External bridge client has logged-in successfully."); - UseKeepAlive = true; - MachineOperator.EnableDiagnostics = false; - SessionIntent = request.Message.Intent; - } - else - { - LogManager.Log("External bridge client login failed, invalid password."); - } - - await SendResponse<ExternalBridgeLoginResponse>(response, container.Token, null, null, IsInSession ? null : "Invalid password or intent."); - } - else - { - LogManager.Log($"External bridge client login failed because the machine is currently printing and '{ExternalBridgeLoginIntent.FullControl}' intent was requested."); - await SendResponse<ExternalBridgeLoginResponse>(new ExternalBridgeLoginResponse(), container.Token, false, ErrorCode.GeneralError, $"Machine connection with '{ExternalBridgeLoginIntent.FullControl}' intent is not permitted while printing."); - } - } - - protected async virtual void OnExternalBridgeLogoutRequest(MessageContainer container) - { - try - { - await SendResponse<ExternalBridgeLogoutResponse>(new ExternalBridgeLogoutResponse(), container.Token); - } - catch (Exception ex) - { - LogManager.Log(ex); - } - finally - { - ClearQueues(); - } - - OnClientDisconnected(); - } - - protected virtual void OnStartApplicationLogsRequest(MessageContainer container) - { - if (SessionIntent == ExternalBridgeLoginIntent.Diagnostics || SessionIntent == ExternalBridgeLoginIntent.FullControl) - { - _app_logs_token = container.Token; - _send_app_logs = true; - SendResponse<StartApplicationLogsResponse>(new StartApplicationLogsResponse(), container.Token); - } - else - { - throw new AuthenticationException("The specified intent does not grant the specified action."); - } - } - - protected virtual void OnStopApplicationLogsRequest(MessageContainer container) - { - if (SessionIntent == ExternalBridgeLoginIntent.Diagnostics || SessionIntent == ExternalBridgeLoginIntent.FullControl) - { - _send_app_logs = false; - SendResponse<StopApplicationLogsResponse>(new StopApplicationLogsResponse() { }, container.Token); - SendResponse<StartApplicationLogsResponse>(new StartApplicationLogsResponse() { }, _app_logs_token, true); - } - else - { - throw new AuthenticationException("The specified intent does not grant the specified action."); - } - } - - protected virtual void OnJobRequest(MessageContainer container) - { - if (SessionIntent != ExternalBridgeLoginIntent.FullControl) - { - throw new InvalidOperationException($"Job execution is disabled while session intent is '{SessionIntent}'."); - } - if (MachineOperator.IsPrinting) - { - throw new InvalidOperationException($"Could not execute job while machine operator status is '{MachineOperator.Status}'."); - } - else - { - OnAnyRequest(container); - } - } - - protected virtual void OnStartEventsNotificationRequest(MessageContainer container) - { - _eventsNotificationsToken = container.Token; - SendResponse<StartEventsNotificationResponse>(new StartEventsNotificationResponse(), container.Token); - } - - protected virtual void OnStopEventsNotificationRequest(MessageContainer container) - { - if (_eventsNotificationsToken != null) - { - SendResponse<StartEventsNotificationResponse>(new StartEventsNotificationResponse(), _eventsNotificationsToken, true); - _eventsNotificationsToken = null; - SendResponse<StopEventsNotificationResponse>(new StopEventsNotificationResponse(), container.Token); - } - } - - protected virtual void OnStartMachineStatusUpdateRequest(MessageContainer container) - { - _machineStatusUpdateToken = container.Token; - SendResponse<StartMachineStatusUpdateResponse>(new StartMachineStatusUpdateResponse(), container.Token); - } - - protected virtual void OnStopMachineStatusUpdateRequest(MessageContainer container) - { - if (_machineStatusUpdateToken != null) - { - SendResponse<StartMachineStatusUpdateResponse>(new StartMachineStatusUpdateResponse(), _machineStatusUpdateToken, true); - _machineStatusUpdateToken = null; - SendResponse<StopMachineStatusUpdateResponse>(new StopMachineStatusUpdateResponse(), container.Token); - } - } - - protected virtual void OnStartDiagnosticsRequest(MessageContainer container) - { - if (_diagnosticsNotificationToken == null) - { - _diagnosticsNotificationToken = container.Token; - _machineOperator.SendContinuousRequest(container); - } - } - - private void OnStopDiagnosticsRequest(MessageContainer container) - { - if (_diagnosticsNotificationToken != null) - { - SendResponse<StartDiagnosticsResponse>(new StartDiagnosticsResponse(), _diagnosticsNotificationToken, true); - _diagnosticsNotificationToken = null; - SendResponse<StopDiagnosticsResponse>(new StopDiagnosticsResponse(), container.Token); - } - } - - protected virtual void OnStartDebugLogRequest(MessageContainer container) - { - _debugLogsNotificationToken = container.Token; - SendResponse<StartDebugLogResponse>(new StartDebugLogResponse(), container.Token); - } - - private void OnStopDebugLogRequest(MessageContainer container) - { - if (_debugLogsNotificationToken != null) - { - SendResponse<StartDebugLogResponse>(new StartDebugLogResponse(), _debugLogsNotificationToken, true); - _debugLogsNotificationToken = null; - SendResponse<StopDebugLogResponse>(new StopDebugLogResponse(), container.Token); - } - } - - private void OnColorProfileRequest(MessageContainer container) - { - var request = MessageFactory.ParseTangoMessageFromContainer<ColorProfileRequest>(container); - - ColorProfileRequestEventArgs e = new ColorProfileRequestEventArgs(request, async () => - { - //Approved. - await SendResponse<ColorProfileResponse>(new ColorProfileResponse() - { - Approved = true - }, container.Token); - await Task.Delay(500); - await base.Disconnect(); - }, - async () => - { - //Declined. - await SendResponse<ColorProfileResponse>(new ColorProfileResponse(), container.Token); - await Task.Delay(500); - await base.Disconnect(); - }); - - ColorProfileRequest?.Invoke(this, e); - } - - private void OnStartPowerDownRequest(MessageContainer container) - { - SendResponse(new StartPowerDownResponse() { }, container.Token, false, ErrorCode.ContinuousResponseAborted, "Power down request is not supported via external bridge."); + catch { } } #endregion diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeTcpClient.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeTcpClient.cs index 573cabb87..bc5323e13 100644 --- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeTcpClient.cs +++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeTcpClient.cs @@ -117,8 +117,6 @@ namespace Tango.Integration.ExternalBridge await Adapter.Disconnect(); throw new AuthenticationException(response.Container.ErrorMessage); } - - Status = MachineStatuses.ReadyToDye; } catch (Exception ex) { @@ -299,7 +297,11 @@ namespace Tango.Integration.ExternalBridge LogManager.Log("External Bridge TCP client disconnected by the remote host."); } catch { } + + SessionLogger.EndSession(); SessionClosed?.Invoke(this, new EventArgs()); + + NotifyContinuousRequestMessagesDisconnection(); } } diff --git a/Software/Visual_Studio/Tango.Logging/ExceptionLogItem.cs b/Software/Visual_Studio/Tango.Logging/ExceptionLogItem.cs index 7c325ee19..dab06455c 100644 --- a/Software/Visual_Studio/Tango.Logging/ExceptionLogItem.cs +++ b/Software/Visual_Studio/Tango.Logging/ExceptionLogItem.cs @@ -13,50 +13,28 @@ namespace Tango.Logging [Serializable] public class ExceptionLogItem : LogItemBase { + private bool _messageSet; + + [NonSerialized] + private Exception _exception; /// <summary> /// Gets or sets the log item exception. /// </summary> - public Exception Exception { get; set; } + public Exception Exception + { + get { return _exception; } + set { _exception = value; } + } /// <summary> - /// Gets or sets the error description. + /// Gets the log message. /// </summary> - public String Description { get; set; } + public override string Message { get; set; } /// <summary> - /// Gets the log message. + /// Gets or sets the error description. /// </summary> - public override string Message - { - get - { - if (Exception is AggregateException) - { - try - { - String message = String.Empty; - - if (Description != null) - { - message += Description + Environment.NewLine; - } - - message += String.Join(Environment.NewLine, (Exception as AggregateException).InnerExceptions.Select(x => x.Message)); - - return message; - } - catch - { - return Exception.Message; - } - } - else - { - return Exception.Message; - } - } - set { } - } + public String Description { get; set; } /// <summary> /// Returns a formatted string of the log item. @@ -65,6 +43,5 @@ namespace Tango.Logging { return String.Format("[{0}] [{6}] [{1}] [{2}] [{3}]: {4}{5}", TimeStamp.ToString("HH:mm:ss.ff"), GetRelativeCallerFilePath(), CallerMethodName, CallerLineNumber, Description, Environment.NewLine + Exception.FlattenException(), Category); } - } } diff --git a/Software/Visual_Studio/Tango.Logging/LogManager.cs b/Software/Visual_Studio/Tango.Logging/LogManager.cs index 98bcaaa28..4f5bbb2ca 100644 --- a/Software/Visual_Studio/Tango.Logging/LogManager.cs +++ b/Software/Visual_Studio/Tango.Logging/LogManager.cs @@ -124,6 +124,7 @@ namespace Tango.Logging log.Exception = e; log.Category = category; log.Description = description; + log.Message = log.Description + Environment.NewLine + log.Exception.FlattenException(); AppendLog(log); diff --git a/Software/Visual_Studio/Tango.Transport/TransporterBase.cs b/Software/Visual_Studio/Tango.Transport/TransporterBase.cs index 7f8bfa016..b8aa96ea6 100644 --- a/Software/Visual_Studio/Tango.Transport/TransporterBase.cs +++ b/Software/Visual_Studio/Tango.Transport/TransporterBase.cs @@ -272,6 +272,26 @@ namespace Tango.Transport return Adapter != null ? $"{ComponentName} ({Adapter.Address})" : ComponentName; } + /// <summary> + /// Notifies all the continuous request messages about disconnection. + /// </summary> + protected virtual void NotifyContinuousRequestMessagesDisconnection() + { + LogManager.Log("Notifying all continuous request messages about disconnection..."); + foreach (var request in _pendingRequests.ToList().Where(x => x.Direction == TransportMessageDirection.Request && x.IsContinuous)) + { + try + { + LogManager.Log($"Notifying continuous request '{(request.Message as ITangoMessage).Type}'..."); + request.SetException(new TransporterDisconnectedException("Transporter disconnected.")); + } + catch (Exception e) + { + System.Diagnostics.Debug.WriteLine(e.ToString()); + } + } + } + #endregion #region Constructors @@ -358,19 +378,7 @@ namespace Tango.Transport } LogManager.Log($"{GetExtendedComponentName()}: Transporter Disconnected..."); - LogManager.Log("Notifying all continuous request messages about disconnection..."); - foreach (var request in _pendingRequests.ToList().Where(x => x.Direction == TransportMessageDirection.Request && x.IsContinuous)) - { - try - { - LogManager.Log($"Notifying continuous request '{(request.Message as ITangoMessage).Type}'..."); - request.SetException(new TransporterDisconnectedException("Transporter disconnected.")); - } - catch (Exception e) - { - System.Diagnostics.Debug.WriteLine(e.ToString()); - } - } + NotifyContinuousRequestMessagesDisconnection(); } /// <summary> @@ -909,20 +917,27 @@ namespace Tango.Transport /// </summary> protected void StartThreads() { - _pullThread = new Thread(PullThreadMethod); - _pullThread.Name = $"{GetExtendedComponentName()} Pull Thread"; - _pullThread.IsBackground = true; - _pullThread.Start(); + try + { + _pullThread = new Thread(PullThreadMethod); + _pullThread.Name = $"{GetExtendedComponentName()} Pull Thread"; + _pullThread.IsBackground = true; + _pullThread.Start(); - _pushThread = new Thread(PushThreadMethod); - _pushThread.Name = $"{GetExtendedComponentName()} Push Thread"; - _pushThread.IsBackground = true; - _pushThread.Start(); + _pushThread = new Thread(PushThreadMethod); + _pushThread.Name = $"{GetExtendedComponentName()} Push Thread"; + _pushThread.IsBackground = true; + _pushThread.Start(); - _keepAliveThread = new Thread(KeepAliveThreadMethod); - _keepAliveThread.Name = $"{GetExtendedComponentName()} KeepAlive Thread"; - _keepAliveThread.IsBackground = true; - _keepAliveThread.Start(); + _keepAliveThread = new Thread(KeepAliveThreadMethod); + _keepAliveThread.Name = $"{GetExtendedComponentName()} KeepAlive Thread"; + _keepAliveThread.IsBackground = true; + _keepAliveThread.Start(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error starting transporter threads."); + } } /// <summary> |
