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 @@
-
+
diff --git a/UI/.idea/libraries/libraries.xml b/UI/.idea/libraries/libraries.xml
index 4034625c6..ddc15483e 100644
--- a/UI/.idea/libraries/libraries.xml
+++ b/UI/.idea/libraries/libraries.xml
@@ -10,14 +10,12 @@
-
-
+
+
-
-
@@ -26,6 +24,8 @@
+
+
@@ -34,15 +34,13 @@
-
-
+
+
-
-
diff --git a/UI/AddSeries/RootFolders/RootFolderCollection.js b/UI/AddSeries/RootFolders/RootFolderCollection.js
index 7f4e66ae5..e7c0caa9e 100644
--- a/UI/AddSeries/RootFolders/RootFolderCollection.js
+++ b/UI/AddSeries/RootFolders/RootFolderCollection.js
@@ -6,5 +6,5 @@ define(['app', 'AddSeries/RootFolders/RootFolderModel'], function () {
model: NzbDrone.AddSeries.RootFolders.RootFolderModel
});
- return new rootFolderCollection();
+ return new rootFolderCollection().BindSignalR();
});
\ No newline at end of file
diff --git a/UI/Mixins/backbone.signalr.mixin.js b/UI/Mixins/backbone.signalr.mixin.js
index 7e1bfa13b..43886aefa 100644
--- a/UI/Mixins/backbone.signalr.mixin.js
+++ b/UI/Mixins/backbone.signalr.mixin.js
@@ -1,7 +1,15 @@
"use strict";
-(function ($) {
- var connection = $.connection('/signalr/series');
+Backbone.Collection.prototype.BindSignalR = function (options) {
+
+ if (!options || !options.url) {
+ console.assert(this.url, 'url must be provided or collection must have url');
+ options = {
+ url: this.url.replace('api', 'signalr')
+ };
+ }
+
+ var self = this;
var _getStatus = function (status) {
switch (status) {
@@ -19,18 +27,21 @@
};
+
+ var connection = $.connection(options.url);
+
connection.stateChanged(function (change) {
-
- console.log('signalR [{0}]'.format(_getStatus(change.newState)));
+ console.debug('{0} [{1}]'.format(options.url, _getStatus(change.newState)));
});
- connection.received(function (data) {
- console.log(data);
+ connection.received(function () {
+ self.fetch();
});
- connection.error(function (error) {
- console.warn(error);
- });
+ connection.start({ transport: ['longPolling'] });
+
+ return this;
+};
+
+
- connection.start();
-})(jQuery);
\ No newline at end of file