diff options
| author | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-02-27 23:49:32 +0200 |
|---|---|---|
| committer | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-02-27 23:49:32 +0200 |
| commit | 5f45be5bae69be7b7e916f02fb6d69b2db60e529 (patch) | |
| tree | 9aff84020b5eca21df7bf0a7b5439e073969cec1 /Software/Visual_Studio/Tango.Integration/ExternalBridge | |
| parent | 03970962af1bfbfc5c13109c3f0a465cf9a1dc29 (diff) | |
| download | Tango-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')
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); } } |
