aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Tango.Integration/ExternalBridge
diff options
context:
space:
mode:
authorRoy Ben Shabat <Roy.mail.net@gmail.com>2020-02-27 23:49:32 +0200
committerRoy Ben Shabat <Roy.mail.net@gmail.com>2020-02-27 23:49:32 +0200
commit5f45be5bae69be7b7e916f02fb6d69b2db60e529 (patch)
tree9aff84020b5eca21df7bf0a7b5439e073969cec1 /Software/Visual_Studio/Tango.Integration/ExternalBridge
parent03970962af1bfbfc5c13109c3f0a465cf9a1dc29 (diff)
downloadTango-5f45be5bae69be7b7e916f02fb6d69b2db60e529.tar.gz
Tango-5f45be5bae69be7b7e916f02fb6d69b2db60e529.zip
Implemented Generic messages support!
Implemented custom external bridge request handlers.
Diffstat (limited to 'Software/Visual_Studio/Tango.Integration/ExternalBridge')
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs10
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiverRequestReceivedEventArgs.cs15
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeRequestHandlerMethodAttribute.cs20
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs102
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeRequestHandler.cs14
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeService.cs15
6 files changed, 174 insertions, 2 deletions
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs
index 679e665f0..400f58c77 100644
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs
@@ -59,6 +59,7 @@ namespace Tango.Integration.ExternalBridge
public event EventHandler<ExternalBridgeReceiverLoginRequestEventArgs> LoginRequest;
public event EventHandler<ColorProfileRequestEventArgs> ColorProfileRequest;
public event EventHandler Disconnected;
+ public event EventHandler<ExternalBridgeReceiverRequestReceivedEventArgs> ReceiverRequestReceived;
#endregion
@@ -178,7 +179,14 @@ namespace Tango.Integration.ExternalBridge
{
if (IsLoggedIn)
{
- OnAnyRequest(container);
+ ExternalBridgeReceiverRequestReceivedEventArgs args = new ExternalBridgeReceiverRequestReceivedEventArgs();
+ args.Container = container;
+ ReceiverRequestReceived?.Invoke(this, args);
+
+ if (!args.Handled)
+ {
+ OnAnyRequest(container);
+ }
}
}
}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiverRequestReceivedEventArgs.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiverRequestReceivedEventArgs.cs
new file mode 100644
index 000000000..682de264c
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiverRequestReceivedEventArgs.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.PMR.Common;
+
+namespace Tango.Integration.ExternalBridge
+{
+ public class ExternalBridgeReceiverRequestReceivedEventArgs
+ {
+ public MessageContainer Container { get; set; }
+ public bool Handled { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeRequestHandlerMethodAttribute.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeRequestHandlerMethodAttribute.cs
new file mode 100644
index 000000000..c326c7dd7
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeRequestHandlerMethodAttribute.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.PMR.Common;
+
+namespace Tango.Integration.ExternalBridge
+{
+ [AttributeUsage(AttributeTargets.Method)]
+ public class ExternalBridgeRequestHandlerMethodAttribute : Attribute
+ {
+ public Type Type { get; set; }
+
+ public ExternalBridgeRequestHandlerMethodAttribute(Type type)
+ {
+ Type = type;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs
index 4395b5f41..ef98db11b 100644
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs
@@ -27,6 +27,8 @@ using Microsoft.AspNet.SignalR.Client;
using Tango.Integration.ExternalBridge.Web;
using Tango.Core.Threading;
using System.Diagnostics;
+using System.Reflection;
+using Newtonsoft.Json;
namespace Tango.Integration.ExternalBridge
{
@@ -41,6 +43,17 @@ namespace Tango.Integration.ExternalBridge
private IHubProxy _proxy;
private bool _isSignalRConnected;
private System.Timers.Timer _signalrPingTimer;
+ private Dictionary<String, RequestHandler> _requestHandlers;
+ private static JsonSerializerSettings _genericMessageSettings = new JsonSerializerSettings()
+ {
+ TypeNameHandling = TypeNameHandling.All
+ };
+
+ private class RequestHandler
+ {
+ public IExternalBridgeRequestHandler Handler { get; set; }
+ public MethodInfo Method { get; set; }
+ }
#region Events
@@ -152,6 +165,8 @@ namespace Tango.Integration.ExternalBridge
/// </summary>
public ExternalBridgeService()
{
+ _requestHandlers = new Dictionary<string, RequestHandler>();
+
SignalRConfiguration = new ExternalBridgeSignalRConfiguration();
TcpTransportAdapterWriteMode = TcpTransportAdapterWriteMode.Interval;
@@ -239,6 +254,7 @@ namespace Tango.Integration.ExternalBridge
receiver.LoginRequest += Receiver_LoginRequest;
receiver.ColorProfileRequest += Receiver_ColorProfileRequest;
receiver.Disconnected += Receiver_Disconnected;
+ receiver.ReceiverRequestReceived += Receiver_ReceiverRequestReceived;
_receivers.Add(receiver);
await receiver.Connect();
}
@@ -255,6 +271,7 @@ namespace Tango.Integration.ExternalBridge
receiver.LoginRequest += Receiver_LoginRequest;
receiver.ColorProfileRequest += Receiver_ColorProfileRequest;
receiver.Disconnected += Receiver_Disconnected;
+ receiver.ReceiverRequestReceived += Receiver_ReceiverRequestReceived;
_receivers.Add(receiver);
await receiver.Connect();
}
@@ -309,6 +326,7 @@ namespace Tango.Integration.ExternalBridge
receiver.LoginRequest -= Receiver_LoginRequest;
receiver.ColorProfileRequest -= Receiver_ColorProfileRequest;
receiver.Disconnected -= Receiver_Disconnected;
+ receiver.ReceiverRequestReceived -= Receiver_ReceiverRequestReceived;
_receivers.Remove(receiver);
@@ -369,6 +387,62 @@ namespace Tango.Integration.ExternalBridge
}
}
+ private void Receiver_ReceiverRequestReceived(object sender, ExternalBridgeReceiverRequestReceivedEventArgs e)
+ {
+ if (e.Container.Type == MessageType.GenericRequest || _requestHandlers.ContainsKey(e.Container.Type.ToString()))
+ {
+ e.Handled = true;
+
+ ThreadFactory.StartNew(() =>
+ {
+ try
+ {
+ var message = MessageFactory.ExtractMessageFromContainer(e.Container);
+
+ if (e.Container.Type != MessageType.GenericRequest) //Handle standard PMR messages.
+ {
+ var handler = _requestHandlers[e.Container.Type.ToString()];
+ handler.Method.Invoke(handler.Handler, new object[]
+ {
+ message,
+ e.Container.Token,
+ sender,
+ });
+ }
+ else //Handle GenericRequest with inner JSON formated generic message.
+ {
+ var genericType = (message as GenericRequest).Type;
+
+ try
+ {
+ if (_requestHandlers.ContainsKey(genericType))
+ {
+ var json = (message as GenericRequest).Data.ToStringUtf8();
+ var innerMessage = JsonConvert.DeserializeObject(json, _genericMessageSettings);
+
+ var handler = _requestHandlers[genericType];
+ handler.Method.Invoke(handler.Handler, new object[]
+ {
+ innerMessage,
+ e.Container.Token,
+ sender,
+ });
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"Error invoking external bridge handler for request '{genericType}'.");
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"An error occurred while trying or invoking an external bridge request handler for '{e.Container.Type}'.");
+ }
+ });
+ }
+ }
+
#endregion
#region Public Methods
@@ -598,5 +672,33 @@ namespace Tango.Integration.ExternalBridge
}
#endregion
+
+ #region Handlers Registration
+
+ public void RegisterRequestHandler(IExternalBridgeRequestHandler handler)
+ {
+ foreach (var method in handler.GetType().GetMethods())
+ {
+ var att = method.GetCustomAttribute<ExternalBridgeRequestHandlerMethodAttribute>();
+ if (att != null)
+ {
+ _requestHandlers.Add(att.Type.Name, new RequestHandler()
+ {
+ Handler = handler,
+ Method = method
+ });
+ }
+ }
+ }
+
+ public void UnregisterRequestHandler(IExternalBridgeRequestHandler handler)
+ {
+ foreach (var h in _requestHandlers.Where(x => x.Value.Handler == handler).ToList())
+ {
+ _requestHandlers.Remove(h.Key);
+ }
+ }
+
+ #endregion
}
}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeRequestHandler.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeRequestHandler.cs
new file mode 100644
index 000000000..fe9e9caee
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeRequestHandler.cs
@@ -0,0 +1,14 @@
+using Google.Protobuf;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Integration.ExternalBridge
+{
+ public interface IExternalBridgeRequestHandler
+ {
+
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeService.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeService.cs
index 7ae09c11d..e2d7bea30 100644
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeService.cs
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeService.cs
@@ -1,4 +1,5 @@
-using System;
+using Google.Protobuf;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -83,5 +84,17 @@ namespace Tango.Integration.ExternalBridge
/// Disconnects the current remote client session.
/// </summary>
void DisconnectFullControlSession();
+
+ /// <summary>
+ /// Registers the request handler.
+ /// </summary>
+ /// <param name="handler">The handler.</param>
+ void RegisterRequestHandler(IExternalBridgeRequestHandler handler);
+
+ /// <summary>
+ /// Unregisters the request handler.
+ /// </summary>
+ /// <param name="handler">The handler.</param>
+ void UnregisterRequestHandler(IExternalBridgeRequestHandler handler);
}
}