diff options
| author | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-08-22 05:15:57 +0300 |
|---|---|---|
| committer | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-08-22 05:15:57 +0300 |
| commit | a9b1c4cb5c4d945565e72e80ac0f938a49da3e5f (patch) | |
| tree | 739307651882bce538653dc76c58c546b2d87699 /Software/Visual_Studio/Tango.Integration/ExternalBridge | |
| parent | 7bd70fcb311c808b65b62e774755dcbd6b0d63cd (diff) | |
| download | Tango-a9b1c4cb5c4d945565e72e80ac0f938a49da3e5f.tar.gz Tango-a9b1c4cb5c4d945565e72e80ac0f938a49da3e5f.zip | |
Implemented pre-connection protocol configuration.
Improved error handling across transport layer.
Improved unexpected app crash for PPC.
Improved transporter request received handlers tunneling.
Diffstat (limited to 'Software/Visual_Studio/Tango.Integration/ExternalBridge')
9 files changed, 141 insertions, 98 deletions
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs index a2f33e1e0..7f9a91651 100644 --- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs +++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Net.Sockets; using System.Security.Authentication; using System.Text; +using System.Threading; using System.Threading.Tasks; using Tango.Core; using Tango.Core.ExtensionMethods; @@ -159,12 +160,30 @@ namespace Tango.Integration.ExternalBridge #region Override Methods - protected override void OnRequestReceived(MessageContainer container) + protected override void OnRequestReceived(RequestReceivedEventArgs e) { - base.OnRequestReceived(container); + base.OnRequestReceived(e); + + if (e.Handled) return; + + var container = e.Container; try { + if (e.Container.Type == MessageType.ConfigureProtocolRequest) + { + var message = MessageFactory.ParseTangoMessageFromContainer<ConfigureProtocolRequest>(container); + SendResponse(new ConfigureProtocolResponse() { Confirmed = true }, container.Token, new TransportResponseConfig() { Immediate = true, Priority = QueuePriority.High }); + + Task.Factory.StartNew(() => + { + Thread.Sleep(200); + Adapter.EnableCompression = message.Message.EnableCompression; + GenericProtocol = message.Message.GenericProtocol; + }); + return; + } + if (!AllowSafetyLevelOperations) { if (ExternalBridgeService.SafetyLevelOperations.Contains(container.Type)) diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs index 58487985b..8bf8b1c58 100644 --- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs +++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs @@ -245,11 +245,11 @@ namespace Tango.Integration.ExternalBridge if (knownMachine == null) { - newMachine = new ExternalBridgeTcpClient(packet.SerialNumber, address, packet.CompressionEnabled); + newMachine = new ExternalBridgeTcpClient(packet.SerialNumber, address); } else { - newMachine = new ExternalBridgeTcpClient(knownMachine, address, packet.CompressionEnabled); + newMachine = new ExternalBridgeTcpClient(knownMachine, address); } LogManager.Log("Found a new machine via TCP " + newMachine.SerialNumber); diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs index 438e475a8..5ec806126 100644 --- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs +++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs @@ -170,11 +170,6 @@ namespace Tango.Integration.ExternalBridge private set { _fullControlSessionReceiver = value; RaisePropertyChangedAuto(); } } - /// <summary> - /// Gets or sets a value indicating whether to broadcast that compression on connected ITransportAdapter is enabled. - /// </summary> - public bool EnableTransportCompression { get; set; } - #endregion #region Constructors @@ -239,7 +234,6 @@ namespace Tango.Integration.ExternalBridge _discoveryService = new UdpDiscoveryService<ExternalBridgeUdpDiscoveryPacket>(_discovery_port, new ExternalBridgeUdpDiscoveryPacket() { SerialNumber = Machine.SerialNumber, - CompressionEnabled = EnableTransportCompression, }); _discoveryService.BeforeBroadcasting -= _discoverySevice_BeforeBroadcasting; @@ -278,7 +272,6 @@ namespace Tango.Integration.ExternalBridge { LogManager.Log("External bridge TCP client connected from: " + e.Socket.GetIPAddress()); ExternalBridgeReceiver receiver = new ExternalBridgeReceiver(e.Socket, MachineOperator); - receiver.Adapter.EnableCompression = EnableTransportCompression; (receiver.Adapter as TcpTransportAdapter).WriteMode = TcpTransportAdapterWriteMode; receiver.LoginRequest += Receiver_LoginRequest; receiver.ColorProfileRequest += Receiver_ColorProfileRequest; @@ -296,7 +289,6 @@ namespace Tango.Integration.ExternalBridge LogManager.Log("External bridge SignalR client connected."); var adapter = new SignalRTransportAdapter(SignalRConfiguration.Address, SignalRConfiguration.Hub, SignalRTransportAdapterMode.JoinSession, Machine.SerialNumber, sessionID); ; - adapter.EnableCompression = EnableTransportCompression; ExternalBridgeReceiver receiver = new ExternalBridgeReceiver(adapter, MachineOperator); receiver.LoginRequest += Receiver_LoginRequest; @@ -432,6 +424,8 @@ namespace Tango.Integration.ExternalBridge private void Receiver_ReceiverRequestReceived(object sender, ExternalBridgeReceiverRequestReceivedEventArgs e) { + ExternalBridgeReceiver receiver = sender as ExternalBridgeReceiver; + if (e.Container.Type == MessageType.GenericRequest || _requestHandlers.ContainsKey(e.Container.Type.ToString())) { e.Handled = true; @@ -465,59 +459,70 @@ namespace Tango.Integration.ExternalBridge }); } } - else //Handle GenericRequest with inner JSON formated generic message. + else //Handle GenericRequest with inner JSON/BSON formated generic message. { var genericType = Type.GetType((message as GenericRequest).Type); - try + if (genericType != null) { - if (_requestHandlers.ContainsKey(genericType.FullName)) + try { - var innerMessage = GenericMessageSerializer.DeserializeFromByteString(genericType, (message as GenericRequest).Data); - - var handler = _requestHandlers[genericType.FullName]; - - if (handler.LoggingMode == RequestHandlerLoggingMode.LogRequestName || handler.LoggingMode == RequestHandlerLoggingMode.LogRequestNameAndContent) + if (_requestHandlers.ContainsKey(genericType.FullName)) { - String content = "."; + var innerMessage = GenericMessageSerializer.DeserializeFromByteString(genericType, (message as GenericRequest).Data, receiver.GenericProtocol); + + var handler = _requestHandlers[genericType.FullName]; - if (handler.LoggingMode == RequestHandlerLoggingMode.LogRequestNameAndContent) + if (handler.LoggingMode == RequestHandlerLoggingMode.LogRequestName || handler.LoggingMode == RequestHandlerLoggingMode.LogRequestNameAndContent) { - content = $":\n{innerMessage.ToJsonString()}"; - } + String content = "."; - LogManager.Log($"'{innerMessage.GetType().Name}' received on '{handler.Method.DeclaringType.Name}.{handler.Method.Name}'{content}"); - } + if (handler.LoggingMode == RequestHandlerLoggingMode.LogRequestNameAndContent) + { + content = $":\n{innerMessage.ToJsonString()}"; + } - if (handler.Method.ReturnType == typeof(Task)) - { - ((Task)handler.Method.Invoke(handler.Handler, new object[] + LogManager.Log($"'{innerMessage.GetType().Name}' received on '{handler.Method.DeclaringType.Name}.{handler.Method.Name}'{content}"); + } + + if (handler.Method.ReturnType == typeof(Task)) { + ((Task)handler.Method.Invoke(handler.Handler, new object[] + { innerMessage, e.Container.Token, sender, - })).Wait(); - } - else - { - handler.Method.Invoke(handler.Handler, new object[] + })).Wait(); + } + else { + handler.Method.Invoke(handler.Handler, new object[] + { innerMessage, e.Container.Token, sender, - }); + }); + } + } + else + { + receiver.SendErrorResponse(new NotSupportedException("Request message not supported on this PPC version."), e.Container.Token); } } - } - catch (Exception ex) - { - LogManager.Log(ex.GetFirstIfAggregate(), $"Error invoking external bridge handler for request '{genericType.Name}'."); - - try + catch (Exception ex) { - (sender as ITransporter).SendErrorResponse(ex.GetFirstIfAggregate(), e.Container.Token); + LogManager.Log(ex.GetFirstIfAggregate(), $"Error invoking external bridge handler for request '{genericType.Name}'."); + + try + { + receiver.SendErrorResponse(ex.GetFirstIfAggregate(), e.Container.Token); + } + catch { } } - catch { } + } + else + { + receiver.SendErrorResponse(new NotSupportedException("Request message not supported on this PPC version."), e.Container.Token); } } } @@ -526,7 +531,7 @@ namespace Tango.Integration.ExternalBridge LogManager.Log(ex, $"An error occurred while trying or invoking an external bridge request handler for '{e.Container.Type}'."); try { - (sender as ITransporter).SendErrorResponse(ex.GetFirstIfAggregate(), e.Container.Token); + receiver.SendErrorResponse(ex.GetFirstIfAggregate(), e.Container.Token); } catch { } } @@ -611,7 +616,6 @@ namespace Tango.Integration.ExternalBridge { SerialNumber = Machine.SerialNumber, Organization = Machine.Organization.Name, - CompressionEnabled = EnableTransportCompression }); _isSignalRConnected = true; diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeSignalRClient.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeSignalRClient.cs index 7c5fc5053..9ad789c06 100644 --- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeSignalRClient.cs +++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeSignalRClient.cs @@ -19,17 +19,12 @@ namespace Tango.Integration.ExternalBridge { public ExternalBridgeSignalRClient(String url, String hub, MachineInfo machineInfo) { - CompressionEnabled = machineInfo.CompressionEnabled; - ComponentName = $"External Bridge SignalR Client {_component_counter++}"; SerialNumber = machineInfo.SerialNumber; IPAddress = machineInfo.IPAddress; Machine = ObservablesStaticCollections.Instance.Machines.SingleOrDefault(x => x.SerialNumber == SerialNumber); - Adapter = new SignalRTransportAdapter(url, hub, SignalRTransportAdapterMode.CreateSession, SerialNumber, null, IPAddress) - { - EnableCompression = CompressionEnabled - }; + Adapter = new SignalRTransportAdapter(url, hub, SignalRTransportAdapterMode.CreateSession, SerialNumber, null, IPAddress); KeepAliveTimeout = TimeSpan.FromSeconds(5); KeepAliveRetries = 2; @@ -38,24 +33,26 @@ namespace Tango.Integration.ExternalBridge public ExternalBridgeSignalRClient(String url, String hub, Machine machine, MachineInfo machineInfo) { - CompressionEnabled = machineInfo.CompressionEnabled; - ComponentName = $"External Bridge SignalR Client {_component_counter++}"; SerialNumber = machine.SerialNumber; IPAddress = machineInfo.IPAddress; Machine = machine; - Adapter = new SignalRTransportAdapter(url, hub, SignalRTransportAdapterMode.CreateSession, SerialNumber, null, IPAddress) - { - EnableCompression = CompressionEnabled - }; + Adapter = new SignalRTransportAdapter(url, hub, SignalRTransportAdapterMode.CreateSession, SerialNumber, null, IPAddress); KeepAliveTimeout = TimeSpan.FromSeconds(5); KeepAliveRetries = 2; UseKeepAlive = false; } - public override async Task Connect(ExternalBridgeLoginRequest login) + /// <summary> + /// Connects to a remote external bridge service using the specified login. + /// </summary> + /// <param name="login">The login request.</param> + /// <param name="protocol">Optional protocol configuration.</param> + /// <returns></returns> + /// <exception cref="AuthenticationException"></exception> + public override async Task Connect(ExternalBridgeLoginRequest login, ConfigureProtocolRequest protocol = null) { if (State != TransportComponentState.Connected) { @@ -66,7 +63,7 @@ namespace Tango.Integration.ExternalBridge State = TransportComponentState.Connected; StartThreads(); - LogManager.Log("External Bridge SignalR Client Connected..."); + LogManager.Log($"{ComponentName}: External Bridge SignalR Client Connected..."); TimeSpan? timeout = null; @@ -77,6 +74,24 @@ namespace Tango.Integration.ExternalBridge var response = await SendRequest<ExternalBridgeLoginRequest, ExternalBridgeLoginResponse>(login, new TransportRequestConfig() { ShouldLog = true, Timeout = timeout }); + if (protocol != null) + { + try + { + var configureResponse = await SendRequest<ConfigureProtocolRequest, ConfigureProtocolResponse>(protocol, new TransportRequestConfig() { ShouldLog = true }); + if (configureResponse.Message.Confirmed) + { + await Task.Delay(500); + Adapter.EnableCompression = protocol.EnableCompression; + GenericProtocol = protocol.GenericProtocol; + } + } + catch (Exception ex) + { + LogManager.Log(ex, $"{ComponentName}: Could not configure remote machine protocol. Could be an old PPC version."); + } + } + ApplicationInformation = response.Message.ApplicationInformation; SessionLogger.CreateSession(); diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeTcpClient.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeTcpClient.cs index 2a6fa1aad..210db008d 100644 --- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeTcpClient.cs +++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeTcpClient.cs @@ -59,11 +59,6 @@ namespace Tango.Integration.ExternalBridge set { _ipAddress = value; RaisePropertyChangedAuto(); } } - /// <summary> - /// Gets or sets a value indicating whether transport compression is required by the remote machine. - /// </summary> - public bool CompressionEnabled { get; set; } - private bool _enableApplicationLogs; /// <summary> /// Gets or sets a value indicating whether to enable receiving application logs. @@ -91,6 +86,11 @@ namespace Tango.Integration.ExternalBridge /// </summary> public ExternalBridgeLoginRequest LoginRequest { get; set; } + /// <summary> + /// Gets or sets the configure protocol request message when using <see cref="Connect"/>. + /// </summary> + public ConfigureProtocolRequest ConfigureProtocolRequest { get; set; } + private ApplicationInformation _applicationInformation; /// <summary> /// Gets or sets the remote application information (PPC). @@ -115,16 +115,17 @@ namespace Tango.Integration.ExternalBridge { throw new InvalidOperationException("No LoginRequest was not specified."); } - return Connect(LoginRequest); + return Connect(LoginRequest, ConfigureProtocolRequest); } /// <summary> /// Connects to a remote external bridge service using the specified login. /// </summary> - /// <param name="login">The login.</param> + /// <param name="login">The login request.</param> + /// <param name="protocol">Optional protocol configuration.</param> /// <returns></returns> - /// <exception cref="AuthenticationException">The machine password is invalid.</exception> - public virtual async Task Connect(ExternalBridgeLoginRequest login) + /// <exception cref="AuthenticationException"></exception> + public virtual async Task Connect(ExternalBridgeLoginRequest login, ConfigureProtocolRequest protocol = null) { if (State != TransportComponentState.Connected) { @@ -135,7 +136,7 @@ namespace Tango.Integration.ExternalBridge State = TransportComponentState.Connected; StartThreads(); - LogManager.Log("External Bridge TCP Client Connected..."); + LogManager.Log($"{ComponentName}: External Bridge TCP Client Connected..."); TimeSpan? timeout = null; @@ -146,6 +147,24 @@ namespace Tango.Integration.ExternalBridge var response = await SendRequest<ExternalBridgeLoginRequest, ExternalBridgeLoginResponse>(login, new TransportRequestConfig() { ShouldLog = true, Timeout = timeout }); + if (protocol != null) + { + try + { + var configureResponse = await SendRequest<ConfigureProtocolRequest, ConfigureProtocolResponse>(protocol, new TransportRequestConfig() { ShouldLog = true }); + if (configureResponse.Message.Confirmed) + { + await Task.Delay(500); + Adapter.EnableCompression = protocol.EnableCompression; + GenericProtocol = protocol.GenericProtocol; + } + } + catch (Exception ex) + { + LogManager.Log(ex, $"{ComponentName}: Could not configure remote machine protocol. Could be an old PPC version."); + } + } + ApplicationInformation = response.Message.ApplicationInformation; SessionLogger.CreateSession(); @@ -286,11 +305,10 @@ namespace Tango.Integration.ExternalBridge /// </summary> /// <param name="serialNumber">The machine serial number.</param> /// <param name="ipAddress">The machine IP address.</param> - public ExternalBridgeTcpClient(String serialNumber, String ipAddress, bool enableCompression) + public ExternalBridgeTcpClient(String serialNumber, String ipAddress) { ComponentName = $"External Bridge TCP Client {_component_counter++}"; SerialNumber = serialNumber; - CompressionEnabled = enableCompression; if (ObservablesStaticCollections.Instance.IsInitialized) { @@ -302,28 +320,21 @@ namespace Tango.Integration.ExternalBridge UseKeepAlive = false; EnableDiagnostics = true; - Adapter = new TcpTransportAdapter(IPAddress, SettingsManager.Default.GetOrCreate<IntegrationSettings>().ExternalBridgeServicePort) - { - EnableCompression = CompressionEnabled - }; + Adapter = new TcpTransportAdapter(IPAddress, SettingsManager.Default.GetOrCreate<IntegrationSettings>().ExternalBridgeServicePort); } - public ExternalBridgeTcpClient(Machine machine, String ipAddress, bool enableCompression) + public ExternalBridgeTcpClient(Machine machine, String ipAddress) { ComponentName = $"External Bridge TCP Client {_component_counter++}"; Machine = machine; SerialNumber = Machine.SerialNumber; - CompressionEnabled = enableCompression; IPAddress = ipAddress; KeepAliveTimeout = TimeSpan.FromSeconds(5); KeepAliveRetries = 2; UseKeepAlive = false; EnableDiagnostics = true; - Adapter = new TcpTransportAdapter(IPAddress, SettingsManager.Default.GetOrCreate<IntegrationSettings>().ExternalBridgeServicePort) - { - EnableCompression = CompressionEnabled - }; + Adapter = new TcpTransportAdapter(IPAddress, SettingsManager.Default.GetOrCreate<IntegrationSettings>().ExternalBridgeServicePort); } /// <summary> @@ -341,15 +352,17 @@ namespace Tango.Integration.ExternalBridge /// Called when a new request has been received. /// </summary> /// <param name="request">The request.</param> - protected async override void OnRequestReceived(MessageContainer request) + protected async override void OnRequestReceived(RequestReceivedEventArgs e) { - base.OnRequestReceived(request); + base.OnRequestReceived(e); + + var container = e.Container; - if (request.Type == MessageType.ExternalBridgeLogoutRequest) + if (container.Type == MessageType.ExternalBridgeLogoutRequest) { try { - await SendResponse<ExternalBridgeLogoutResponse>(new ExternalBridgeLogoutResponse(), request.Token); + await SendResponse<ExternalBridgeLogoutResponse>(new ExternalBridgeLogoutResponse(), container.Token); } catch { } diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeClient.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeClient.cs index 563ef9418..d336b6b70 100644 --- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeClient.cs +++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeClient.cs @@ -28,11 +28,6 @@ namespace Tango.Integration.ExternalBridge String SerialNumber { get; set; } /// <summary> - /// Gets or sets a value indicating whether transport compression is required by the remote machine. - /// </summary> - bool CompressionEnabled { get; set; } - - /// <summary> /// Gets the database machine associated with this client. /// </summary> Machine Machine { get; } diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeSecureClient.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeSecureClient.cs index 7d35963d4..aaf7efc2d 100644 --- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeSecureClient.cs +++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeSecureClient.cs @@ -21,8 +21,9 @@ namespace Tango.Integration.ExternalBridge /// <summary> /// Connects to a remote external bridge service using the specified login. /// </summary> - /// <param name="login">The login.</param> + /// <param name="login">The login request.</param> + /// <param name="protocol">Optional protocol configuration.</param> /// <returns></returns> - Task Connect(ExternalBridgeLoginRequest login); + Task Connect(ExternalBridgeLoginRequest login, ConfigureProtocolRequest protocol = null); } } diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeService.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeService.cs index f6a4ca110..c7d2c8d5c 100644 --- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeService.cs +++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeService.cs @@ -62,11 +62,6 @@ namespace Tango.Integration.ExternalBridge TcpTransportAdapterWriteMode TcpTransportAdapterWriteMode { get; set; } /// <summary> - /// Gets or sets a value indicating whether to broadcast that compression on connected ITransportAdapter is enabled. - /// </summary> - bool EnableTransportCompression { get; set; } - - /// <summary> /// Gets a value indicating whether this instance is started. /// </summary> bool IsStarted { get; } diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/Web/MachineInfo.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/Web/MachineInfo.cs index 578dd9640..cccc24c35 100644 --- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/Web/MachineInfo.cs +++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/Web/MachineInfo.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.PMR.Integration; +using Tango.Transport; namespace Tango.Integration.ExternalBridge.Web { @@ -11,7 +13,6 @@ namespace Tango.Integration.ExternalBridge.Web public String SerialNumber { get; set; } public String Organization { get; set; } public String IPAddress { get; set; } - public bool CompressionEnabled { get; set; } public MachineInfo() { |
