From a6aba169026a15615d9084c2eff8ad0f31fbdf63 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Sun, 5 May 2013 17:33:43 -0700 Subject: [PATCH] Bind any collection to SignalR with a single call. --- NzbDrone.Api/NzbDrone.Api.csproj | 2 + .../RootFolders/RootFolderConnection.cs | 13 ++++++ .../SignalR/BasicResourceConnection.cs | 5 ++- NzbDrone.Api/SignalR/Serializer.cs | 42 +++++++++++++++++++ .../SignalR/SignalrDependencyResolver.cs | 3 ++ NzbDrone.Common/IJsonSerializer.cs | 10 ++++- NzbDrone/Owin/MiddleWare/SignalRMiddleWare.cs | 3 +- UI/.idea/dictionaries/Keivan.xml | 1 + UI/.idea/jsLibraryMappings.xml | 2 +- UI/.idea/jsLinters/jshint.xml | 2 +- UI/.idea/libraries/libraries.xml | 14 +++---- .../RootFolders/RootFolderCollection.js | 2 +- UI/Mixins/backbone.signalr.mixin.js | 33 ++++++++++----- 13 files changed, 106 insertions(+), 26 deletions(-) create mode 100644 NzbDrone.Api/RootFolders/RootFolderConnection.cs create mode 100644 NzbDrone.Api/SignalR/Serializer.cs diff --git a/NzbDrone.Api/NzbDrone.Api.csproj b/NzbDrone.Api/NzbDrone.Api.csproj index 0e3ca2be7..1787b9316 100644 --- a/NzbDrone.Api/NzbDrone.Api.csproj +++ b/NzbDrone.Api/NzbDrone.Api.csproj @@ -121,6 +121,7 @@ + @@ -144,6 +145,7 @@ + diff --git a/NzbDrone.Api/RootFolders/RootFolderConnection.cs b/NzbDrone.Api/RootFolders/RootFolderConnection.cs new file mode 100644 index 000000000..0068cc972 --- /dev/null +++ b/NzbDrone.Api/RootFolders/RootFolderConnection.cs @@ -0,0 +1,13 @@ +using NzbDrone.Api.SignalR; +using NzbDrone.Core.RootFolders; + +namespace NzbDrone.Api.RootFolders +{ + public class RootFolderConnection : BasicResourceConnection + { + public override string Resource + { + get { return "RootFolder"; } + } + } +} diff --git a/NzbDrone.Api/SignalR/BasicResourceConnection.cs b/NzbDrone.Api/SignalR/BasicResourceConnection.cs index 1a3a2af78..31c6b2e53 100644 --- a/NzbDrone.Api/SignalR/BasicResourceConnection.cs +++ b/NzbDrone.Api/SignalR/BasicResourceConnection.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Microsoft.AspNet.SignalR; +using Microsoft.AspNet.SignalR.Infrastructure; using NLog; using NzbDrone.Common.Messaging; using NzbDrone.Core.Datastore; @@ -14,6 +15,7 @@ namespace NzbDrone.Api.SignalR { private readonly Logger _logger; + public BasicResourceConnection() { _logger = LogManager.GetCurrentClassLogger(); @@ -33,7 +35,8 @@ namespace NzbDrone.Api.SignalR public void HandleAsync(ModelEvent message) { - Connection.Broadcast(message); + var context =((ConnectionManager)GlobalHost.ConnectionManager).GetConnection(GetType()); + context.Connection.Broadcast(message); } } } \ No newline at end of file diff --git a/NzbDrone.Api/SignalR/Serializer.cs b/NzbDrone.Api/SignalR/Serializer.cs new file mode 100644 index 000000000..b2b853c24 --- /dev/null +++ b/NzbDrone.Api/SignalR/Serializer.cs @@ -0,0 +1,42 @@ +using System; +using System.IO; +using Microsoft.AspNet.SignalR.Json; + +namespace NzbDrone.Api.SignalR +{ + public class Serializer : IJsonSerializer + { + private readonly Common.IJsonSerializer _nzbDroneSerializer; + private JsonNetSerializer _signalRSerializer; + + public Serializer(Common.IJsonSerializer nzbDroneSerializer) + { + _signalRSerializer = new JsonNetSerializer(); + _nzbDroneSerializer = nzbDroneSerializer; + + } + + public void Serialize(object value, TextWriter writer) + { + if (value.GetType().FullName.StartsWith("NzbDrone")) + { + _nzbDroneSerializer.Serialize(value, writer); + } + else + { + _signalRSerializer.Serialize(value, writer); + } + + } + + public object Parse(string json, Type targetType) + { + if (targetType.FullName.StartsWith("NzbDrone")) + { + return _nzbDroneSerializer.Deserialize(json, targetType); + } + + return _signalRSerializer.Parse(json, targetType); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Api/SignalR/SignalrDependencyResolver.cs b/NzbDrone.Api/SignalR/SignalrDependencyResolver.cs index e17d3623d..bbdc5fa14 100644 --- a/NzbDrone.Api/SignalR/SignalrDependencyResolver.cs +++ b/NzbDrone.Api/SignalR/SignalrDependencyResolver.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using Microsoft.AspNet.SignalR; +using Microsoft.AspNet.SignalR.Json; using TinyIoC; namespace NzbDrone.Api.SignalR @@ -13,6 +14,8 @@ namespace NzbDrone.Api.SignalR public static void Register(TinyIoCContainer container) { GlobalHost.DependencyResolver = new SignalrDependencyResolver(container); + + container.Register().AsSingleton(); } private SignalrDependencyResolver(TinyIoCContainer container) diff --git a/NzbDrone.Common/IJsonSerializer.cs b/NzbDrone.Common/IJsonSerializer.cs index 0151f1eb1..f43c9dd97 100644 --- a/NzbDrone.Common/IJsonSerializer.cs +++ b/NzbDrone.Common/IJsonSerializer.cs @@ -9,6 +9,7 @@ namespace NzbDrone.Common { T Deserialize(string json) where T : class, new(); string Serialize(object obj); + void Serialize(TModel model, TextWriter textWriter); void Serialize(TModel model, Stream outputStream); object Deserialize(string json, Type type); } @@ -55,13 +56,18 @@ namespace NzbDrone.Common } - public void Serialize(TModel model, Stream outputStream) + public void Serialize(TModel model, TextWriter outputStream) { - var jsonTextWriter = new JsonTextWriter(new StreamWriter(outputStream)); + var jsonTextWriter = new JsonTextWriter(outputStream); _jsonNetSerializer.Serialize(jsonTextWriter, model); jsonTextWriter.Flush(); } + public void Serialize(TModel model, Stream outputStream) + { + Serialize(model, new StreamWriter(outputStream)); + } + } } \ No newline at end of file diff --git a/NzbDrone/Owin/MiddleWare/SignalRMiddleWare.cs b/NzbDrone/Owin/MiddleWare/SignalRMiddleWare.cs index 2b21f9a7b..9975ea8d5 100644 --- a/NzbDrone/Owin/MiddleWare/SignalRMiddleWare.cs +++ b/NzbDrone/Owin/MiddleWare/SignalRMiddleWare.cs @@ -23,7 +23,8 @@ namespace NzbDrone.Owin.MiddleWare { foreach (var nzbDronePersistentConnection in _persistentConnections) { - appBuilder.MapConnection("signalr/series", nzbDronePersistentConnection.GetType(), new ConnectionConfiguration { EnableCrossDomain = true }); + var url = string.Format("signalr/{0}", nzbDronePersistentConnection.Resource.Trim('/')); + appBuilder.MapConnection(url, nzbDronePersistentConnection.GetType(), new ConnectionConfiguration { EnableCrossDomain = true }); } } diff --git a/UI/.idea/dictionaries/Keivan.xml b/UI/.idea/dictionaries/Keivan.xml index 8c116d521..6089d177c 100644 --- a/UI/.idea/dictionaries/Keivan.xml +++ b/UI/.idea/dictionaries/Keivan.xml @@ -7,6 +7,7 @@ rootdir rootfolder rootfolders + signalr thetvdb trakt tvdb diff --git a/UI/.idea/jsLibraryMappings.xml b/UI/.idea/jsLibraryMappings.xml index c932efdc1..c09b6ec1f 100644 --- a/UI/.idea/jsLibraryMappings.xml +++ b/UI/.idea/jsLibraryMappings.xml @@ -1,7 +1,7 @@ - + diff --git a/UI/.idea/jsLinters/jshint.xml b/UI/.idea/jsLinters/jshint.xml index 103e7ac67..a01e3f32e 100644 --- a/UI/.idea/jsLinters/jshint.xml +++ b/UI/.idea/jsLinters/jshint.xml @@ -61,7 +61,7 @@