From 8d1933f305e8fb4aa4cc7633fa02c419d77766ff Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Wed, 15 Jan 2020 21:13:45 +0200 Subject: External bridge improvements. --- .../Views/ConnectedMachineView.xaml | 48 ++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ConnectedMachineView.xaml') diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ConnectedMachineView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ConnectedMachineView.xaml index e69ac516e..a5283f346 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ConnectedMachineView.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ConnectedMachineView.xaml @@ -32,6 +32,10 @@ + + + + @@ -65,6 +69,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.3.1 From 1af7b84af6fa0a7663013288ca7b28c4774fc846 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Wed, 15 Jan 2020 23:43:53 +0200 Subject: External Bridge SignalR improvements. --- .../Views/ConnectedMachineView.xaml | 4 +- .../PPC/Tango.PPC.UI/Views/ExternalBridgeView.xaml | 4 +- .../ExternalBridgeClientConnectedEventArgs.cs | 2 +- .../ExternalBridge/ExternalBridgeReceiver.cs | 2 +- .../ExternalBridgeReceiverLoginRequestEventArgs.cs | 2 +- .../ExternalBridge/ExternalBridgeService.cs | 4 +- .../ExternalBridge/ExternalBridgeSignalRClient.cs | 5 +- .../Adapters/SignalRTransportAdapter.cs | 199 ++++++++++++++------- .../Adapters/SignalRTransportAdapterMode.cs | 23 +++ .../Tango.Transport/Tango.Transport.csproj | 1 + 10 files changed, 173 insertions(+), 73 deletions(-) create mode 100644 Software/Visual_Studio/Tango.Transport/Adapters/SignalRTransportAdapterMode.cs (limited to 'Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ConnectedMachineView.xaml') diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ConnectedMachineView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ConnectedMachineView.xaml index a5283f346..e58885efc 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ConnectedMachineView.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ConnectedMachineView.xaml @@ -84,8 +84,8 @@ - - + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/ExternalBridgeView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/ExternalBridgeView.xaml index 377d1b531..fddd15fe7 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/ExternalBridgeView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/ExternalBridgeView.xaml @@ -48,8 +48,8 @@ This machine is currently being controlled by a remote client - IP Address: - + Address: + Host Name: diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeClientConnectedEventArgs.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeClientConnectedEventArgs.cs index 2bfe60477..176dae4b3 100644 --- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeClientConnectedEventArgs.cs +++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeClientConnectedEventArgs.cs @@ -11,7 +11,7 @@ namespace Tango.Integration.ExternalBridge { public ExternalBridgeLoginRequest Request { get; set; } - public String IpAddress { get; set; } + public String Address { get; set; } public bool Confirmed { get; set; } } diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs index 4796072f3..fc00bd18e 100644 --- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs +++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs @@ -269,7 +269,7 @@ namespace Tango.Integration.ExternalBridge Disconnect().GetAwaiter().GetResult(); }); - args.IpAddress = Adapter.Address; + args.Address = Adapter.Address; args.Request = request; LoginRequest?.Invoke(this, args); diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiverLoginRequestEventArgs.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiverLoginRequestEventArgs.cs index 2a3dd52a9..b5c1ec458 100644 --- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiverLoginRequestEventArgs.cs +++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiverLoginRequestEventArgs.cs @@ -22,7 +22,7 @@ namespace Tango.Integration.ExternalBridge public ExternalBridgeLoginRequest Request { get; set; } - public String IpAddress { get; set; } + public String Address { get; set; } public void Confirm(Machine machine, DeviceInformation deviceInformation) { diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs index fb56194e8..335150491 100644 --- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs +++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs @@ -235,7 +235,7 @@ namespace Tango.Integration.ExternalBridge { LogManager.Log("External bridge SignalR client connected."); - var adapter = new SignalRTransportAdapter(SignalRConfiguration.Address, SignalRConfiguration.Hub, SignalRTransportAdapter.SignalRTransportAdapterMode.JoinSession, Machine.SerialNumber, sessionID); ; + var adapter = new SignalRTransportAdapter(SignalRConfiguration.Address, SignalRConfiguration.Hub, SignalRTransportAdapterMode.JoinSession, Machine.SerialNumber, sessionID); ; ExternalBridgeReceiver receiver = new ExternalBridgeReceiver(adapter, MachineOperator); receiver.LoginRequest += Receiver_LoginRequest; @@ -327,7 +327,7 @@ namespace Tango.Integration.ExternalBridge ExternalBridgeClientConnectedEventArgs args = new ExternalBridgeClientConnectedEventArgs(); args.Request = request; - args.IpAddress = e.IpAddress; + args.Address = e.Address; ConnectionRequest?.Invoke(this, args); var response = new ExternalBridgeLoginResponse(); diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeSignalRClient.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeSignalRClient.cs index d541f323a..e2aae9eb8 100644 --- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeSignalRClient.cs +++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeSignalRClient.cs @@ -18,13 +18,16 @@ namespace Tango.Integration.ExternalBridge { public ExternalBridgeSignalRClient(String url, String hub, String serialNumber) { + ComponentName = $"External Bridge SignalR Client {_component_counter++}"; + SerialNumber = serialNumber; IPAddress = hub; Machine = ObservablesStaticCollections.Instance.Machines.SingleOrDefault(x => x.SerialNumber == serialNumber); - Adapter = new SignalRTransportAdapter(url, hub, SignalRTransportAdapter.SignalRTransportAdapterMode.CreateSession, serialNumber); + Adapter = new SignalRTransportAdapter(url, hub, SignalRTransportAdapterMode.CreateSession, serialNumber); KeepAliveTimeout = TimeSpan.FromSeconds(5); KeepAliveRetries = 2; + UseKeepAlive = false; } public override async Task Connect(ExternalBridgeLoginRequest login) diff --git a/Software/Visual_Studio/Tango.Transport/Adapters/SignalRTransportAdapter.cs b/Software/Visual_Studio/Tango.Transport/Adapters/SignalRTransportAdapter.cs index 2324e140c..94de34237 100644 --- a/Software/Visual_Studio/Tango.Transport/Adapters/SignalRTransportAdapter.cs +++ b/Software/Visual_Studio/Tango.Transport/Adapters/SignalRTransportAdapter.cs @@ -7,29 +7,54 @@ using Tango.Core; namespace Tango.Transport.Adapters { + /// + /// Represents an adapter for communicating via SignalR protocol. + /// + /// public class SignalRTransportAdapter : TransportAdapterBase { - public enum SignalRTransportAdapterMode - { - CreateSession, - JoinSession - } - private IHubProxy _proxy; private HubConnection _connection; private Thread _pushThread; private ProducerConsumerQueue _pushQueue; + /// + /// Gets or sets the URL of the SignalR service. + /// + public String Url { get; set; } + + /// + /// Gets or sets the SignalR hub name. + /// public String Hub { get; set; } + /// + /// Gets or sets the serial number of the remote machine (Use onlt for ) mode. + /// public String SerialNumber { get; set; } - public String SessionID { get; set; } + /// + /// Gets or sets the remote session identifier. + /// + public String SessionID { get; private set; } + /// + /// Gets or sets the interval of write operation. + /// Unlike other adapters, the SignalR adapter accumulates multiple write operations into one chunk. + /// + public TimeSpan WriteInterval { get; set; } + + /// + /// Gets or sets the adapter mode. + /// public SignalRTransportAdapterMode Mode { get; set; } + /// + /// Initializes a new instance of the class. + /// public SignalRTransportAdapter() : base() { + WriteInterval = TimeSpan.FromSeconds(1); ComponentName = $"SignalR Adapter {_component_counter++}"; _pushThread = new Thread(PushThreadMethod); _pushThread.IsBackground = true; @@ -37,73 +62,51 @@ namespace Tango.Transport.Adapters _pushQueue = new ProducerConsumerQueue(); } + /// + /// Initializes a new instance of the class. + /// + /// The service address. + /// The hub name. + /// The adapter mode. + /// The machine serial number (when creating session). + /// The session identifier (when joining session). public SignalRTransportAdapter(String url, String hub, SignalRTransportAdapterMode mode, String serialNumber = null, String sessionID = null) : this() { - Address = url; + Url = url; Hub = hub; Mode = mode; SerialNumber = serialNumber; SessionID = sessionID; + Address = sessionID; } + /// + /// Writes the specified data to the stream. + /// + /// The data. public override void Write(byte[] data) { _pushQueue.BlockEnqueue(data); } - private void PushThreadMethod() - { - while (State == TransportComponentState.Connected) - { - List dataCollection = new List(); - - var data = _pushQueue.BlockDequeue(); - var first = true; - - while (_pushQueue.Count > 0 || first) - { - if (!first) - { - data = _pushQueue.BlockDequeue(); - } - else - { - first = false; - } - - var compressed = Compression.SevenZipHelper.Compress(data); - dataCollection.Add(compressed); - } - - if (dataCollection.Count > 0) - { - try - { - _proxy.Invoke("Write", dataCollection).GetAwaiter().GetResult(); - } - catch (Exception ex) - { - OnFailed(ex); - return; - } - } - - Thread.Sleep(1000); - } - } - + /// + /// Connects the transport component. + /// + /// public override Task Connect() { if (State != TransportComponentState.Connected) { + LogManager.Log("Connecting SignalR adapter..."); + bool completed = false; TaskCompletionSource completionSource = new TaskCompletionSource(); - _connection = new HubConnection(Address); + _connection = new HubConnection(Url); _proxy = _connection.CreateHubProxy(Hub); - Core.Threading.TimeoutTask.StartNew(() => + Core.Threading.TimeoutTask.StartNew(() => { if (!completed) { @@ -119,6 +122,8 @@ namespace Tango.Transport.Adapters { if (!completed) { + LogManager.Log($"SignalR adapter session created ({SessionID})..."); + LogManager.Log("SingalR adapter connected."); completed = true; State = TransportComponentState.Connected; _pushThread.Start(); @@ -133,11 +138,15 @@ namespace Tango.Transport.Adapters { if (Mode == SignalRTransportAdapterMode.CreateSession) { + LogManager.Log("Creating SignalR adapter Session..."); SessionID = await _proxy.Invoke("CreateSession", SerialNumber); + Address = SessionID; } else { + LogManager.Log($"Joining SignalR adapter session ({SessionID})..."); await _proxy.Invoke("JoinSession", SessionID); + LogManager.Log("SingalR adapter connected."); } if (Mode == SignalRTransportAdapterMode.JoinSession) @@ -161,25 +170,89 @@ namespace Tango.Transport.Adapters return Task.FromResult(true); } - private void OnDataAvailable(List dataCollection) + /// + /// Disconnects the transport component. + /// + /// + public override Task Disconnect() { - foreach (var data in dataCollection) + return Task.Factory.StartNew(() => { - OnDataAvailable(Compression.SevenZipHelper.Decompress(data)); - } + if (State == TransportComponentState.Connected) + { + LogManager.Log("Disconnecting SignalR adapter..."); + Core.Threading.TimeoutTask.StartNew(() => + { + try + { + _connection.Stop(); + _connection.Dispose(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error disposing SignalR adapter connection."); + } + }, TimeSpan.FromSeconds(5)); + State = TransportComponentState.Disconnected; + LogManager.Log("SignalR adapter disconnected."); + } + }); } - public override Task Disconnect() + /// + /// Handles the write operation. + /// + private void PushThreadMethod() { - return Task.Factory.StartNew(() => + while (State == TransportComponentState.Connected) { - Core.Threading.TimeoutTask.StartNew(() => + List dataCollection = new List(); + + var data = _pushQueue.BlockDequeue(); + var first = true; + + while (_pushQueue.Count > 0 || first) { - _connection.Stop(); - _connection.Dispose(); - },TimeSpan.FromSeconds(5)); - State = TransportComponentState.Disconnected; - }); + if (!first) + { + data = _pushQueue.BlockDequeue(); + } + else + { + first = false; + } + + var compressed = Compression.SevenZipHelper.Compress(data); + dataCollection.Add(compressed); + } + + if (dataCollection.Count > 0) + { + try + { + _proxy.Invoke("Write", dataCollection).GetAwaiter().GetResult(); + } + catch (Exception ex) + { + OnFailed(ex); + return; + } + } + + Thread.Sleep(WriteInterval); + } + } + + /// + /// Called when new data is available. + /// + /// The data collection. + private void OnDataAvailable(List dataCollection) + { + foreach (var data in dataCollection) + { + OnDataAvailable(Compression.SevenZipHelper.Decompress(data)); + } } } } diff --git a/Software/Visual_Studio/Tango.Transport/Adapters/SignalRTransportAdapterMode.cs b/Software/Visual_Studio/Tango.Transport/Adapters/SignalRTransportAdapterMode.cs new file mode 100644 index 000000000..d2335b60b --- /dev/null +++ b/Software/Visual_Studio/Tango.Transport/Adapters/SignalRTransportAdapterMode.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Transport.Adapters +{ + /// + /// Represents a mode. + /// + public enum SignalRTransportAdapterMode + { + /// + /// The adapter should initiate a session with a remote adapter. + /// + CreateSession, + /// + /// The adapter should join an existing session. + /// + JoinSession + } +} diff --git a/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj b/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj index a49b68520..9ade854c5 100644 --- a/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj +++ b/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj @@ -79,6 +79,7 @@ + -- cgit v1.3.1