Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Changed .NET client HubInvocation and related types to use JToken dir…

…ectly.

- Optimized type conversation so we don't end up parsing JSON twice on hub calls.
  • Loading branch information...
commit 50cefbba422a46adb1345bd4f22e49be7ecc52d2 1 parent 6998c77
@davidfowl davidfowl authored
View
3  SignalR.Client/Hubs/HubInvocation.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using Newtonsoft.Json.Linq;
namespace SignalR.Client.Hubs
{
@@ -6,7 +7,7 @@ public class HubInvocation
{
public string Hub { get; set; }
public string Method { get; set; }
- public object[] Args { get; set; }
+ public JToken[] Args { get; set; }
public Dictionary<string, object> State { get; set; }
}
}
View
11 SignalR.Client/Hubs/HubProxy.cs
@@ -5,6 +5,7 @@
#endif
using System.Threading.Tasks;
using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
namespace SignalR.Client.Hubs
{
@@ -68,11 +69,17 @@ public Task<T> Invoke<T>(string method, params object[] args)
throw new ArgumentNullException("method");
}
+ var tokenifiedArguments = new JToken[args.Length];
+ for (int i = 0; i < tokenifiedArguments.Length; i++)
+ {
+ tokenifiedArguments[i] = JToken.FromObject(args[i]);
+ }
+
var hubData = new HubInvocation
{
Hub = _hubName,
Method = method,
- Args = args,
+ Args = tokenifiedArguments,
State = _state
};
@@ -121,7 +128,7 @@ public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, o
}
#endif
- public void InvokeEvent(string eventName, object[] args)
+ public void InvokeEvent(string eventName, JToken[] args)
{
Subscription eventObj;
if (_subscriptions.TryGetValue(eventName, out eventObj))
View
35 SignalR.Client/Hubs/HubProxyExtensions.cs
@@ -1,5 +1,5 @@
using System;
-using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
using SignalR.Client.Infrastructure;
namespace SignalR.Client.Hubs
@@ -33,7 +33,7 @@ public static IDisposable On(this IHubProxy proxy, string eventName, Action onDa
{
Subscription subscription = proxy.Subscribe(eventName);
- Action<object[]> handler = args =>
+ Action<JToken[]> handler = args =>
{
onData();
};
@@ -54,7 +54,7 @@ public static IDisposable On<T>(this IHubProxy proxy, string eventName, Action<T
{
Subscription subscription = proxy.Subscribe(eventName);
- Action<object[]> handler = args =>
+ Action<JToken[]> handler = args =>
{
onData(Convert<T>(args[0]));
};
@@ -75,7 +75,7 @@ public static IDisposable On<T>(this IHubProxy proxy, string eventName, Action<T
{
Subscription subscription = proxy.Subscribe(eventName);
- Action<object[]> handler = args =>
+ Action<JToken[]> handler = args =>
{
onData(Convert<T1>(args[0]),
Convert<T2>(args[1]));
@@ -97,7 +97,7 @@ public static IDisposable On<T>(this IHubProxy proxy, string eventName, Action<T
{
Subscription subscription = proxy.Subscribe(eventName);
- Action<object[]> handler = args =>
+ Action<JToken[]> handler = args =>
{
onData(Convert<T1>(args[0]),
Convert<T2>(args[1]),
@@ -120,7 +120,7 @@ public static IDisposable On<T>(this IHubProxy proxy, string eventName, Action<T
{
Subscription subscription = proxy.Subscribe(eventName);
- Action<object[]> handler = args =>
+ Action<JToken[]> handler = args =>
{
onData(Convert<T1>(args[0]),
Convert<T2>(args[1]),
@@ -157,7 +157,7 @@ public static IDisposable On(this IHubProxy proxy, string eventName, Action<dyna
{
Subscription subscription = proxy.Subscribe(eventName);
- Action<object[]> handler = args =>
+ Action<JToken[]> handler = args =>
{
onData(Convert<T1>(args[0]),
Convert<T2>(args[1]),
@@ -182,7 +182,7 @@ public static IDisposable On(this IHubProxy proxy, string eventName, Action<dyna
{
Subscription subscription = proxy.Subscribe(eventName);
- Action<object[]> handler = args =>
+ Action<JToken[]> handler = args =>
{
onData(Convert<T1>(args[0]),
Convert<T2>(args[1]),
@@ -208,7 +208,7 @@ public static IDisposable On(this IHubProxy proxy, string eventName, Action<dyna
{
Subscription subscription = proxy.Subscribe(eventName);
- Action<object[]> handler = args =>
+ Action<JToken[]> handler = args =>
{
onData(Convert<T1>(args[0]),
Convert<T2>(args[1]),
@@ -235,19 +235,26 @@ public static IObservable<object[]> Observe(this IHubProxy proxy, string eventNa
return new Hubservable(proxy, eventName);
}
#endif
- private static T Convert<T>(object obj)
+ private static T Convert<T>(object value)
{
- if (obj == null)
+ if (value == null)
{
return default(T);
}
- if (typeof(T).IsAssignableFrom(obj.GetType()))
+ var obj = value as JToken ?? JToken.FromObject(value);
+
+ return Convert<T>(obj);
+ }
+
+ private static T Convert<T>(JToken obj)
+ {
+ if (obj == null)
{
- return (T)obj;
+ return default(T);
}
- return JsonConvert.DeserializeObject<T>(obj.ToString());
+ return obj.ToObject<T>();
}
}
}
View
5 SignalR.Client/Hubs/Subscription.cs
@@ -1,4 +1,5 @@
using System;
+using Newtonsoft.Json.Linq;
namespace SignalR.Client.Hubs
{
@@ -7,9 +8,9 @@ namespace SignalR.Client.Hubs
/// </summary>
public class Subscription
{
- public event Action<object[]> Data;
+ public event Action<JToken[]> Data;
- internal void OnData(object[] data)
+ internal void OnData(JToken[] data)
{
if (Data != null)
{
View
70 SignalR.Tests/HubFacts.cs
@@ -95,7 +95,7 @@ public void GenericTaskWithException()
Assert.Equal("Exception of type 'System.Exception' was thrown.", ex.GetBaseException().Message);
connection.Stop();
- }
+ }
[Fact]
public void Overloads()
@@ -148,7 +148,7 @@ public void ChangeHubUrl()
Assert.NotNull(id);
wh.Set();
});
-
+
connection.Start(host).Wait();
hub.Invoke("DynamicTask").Wait();
@@ -156,5 +156,71 @@ public void ChangeHubUrl()
Assert.True(wh.WaitOne(TimeSpan.FromSeconds(5)));
connection.Stop();
}
+
+ [Fact]
+ public void GuidTest()
+ {
+ var host = new MemoryHost();
+ host.MapHubs();
+ var connection = new Client.Hubs.HubConnection("http://site/");
+
+ var hub = connection.CreateProxy("demo");
+
+ var wh = new ManualResetEvent(false);
+
+ hub.On<Guid>("TestGuid", id =>
+ {
+ Assert.NotNull(id);
+ wh.Set();
+ });
+
+ connection.Start(host).Wait();
+
+ hub.Invoke("TestGuid").Wait();
+
+ Assert.True(wh.WaitOne(TimeSpan.FromSeconds(5)));
+ connection.Stop();
+ }
+
+ [Fact]
+ public void ComplexPersonState()
+ {
+ var host = new MemoryHost();
+ host.MapHubs();
+ var connection = new Client.Hubs.HubConnection("http://site/");
+
+ var hub = connection.CreateProxy("demo");
+
+ var wh = new ManualResetEvent(false);
+
+ connection.Start(host).Wait();
+
+ var person = new SignalR.Samples.Hubs.DemoHub.DemoHub.Person
+ {
+ Address = new SignalR.Samples.Hubs.DemoHub.DemoHub.Address
+ {
+ Street = "Redmond",
+ Zip = "98052"
+ },
+ Age = 25,
+ Name = "David"
+ };
+
+ var person1 = hub.Invoke<SignalR.Samples.Hubs.DemoHub.DemoHub.Person>("ComplexType", person).Result;
+ var person2 = hub.GetValue<SignalR.Samples.Hubs.DemoHub.DemoHub.Person>("person");
+
+ Assert.NotNull(person1);
+ Assert.NotNull(person2);
+ Assert.Equal("David", person1.Name);
+ Assert.Equal("David", person2.Name);
+ Assert.Equal(25, person1.Age);
+ Assert.Equal(25, person2.Age);
+ Assert.Equal("Redmond", person1.Address.Street);
+ Assert.Equal("Redmond", person2.Address.Street);
+ Assert.Equal("98052", person1.Address.Zip);
+ Assert.Equal("98052", person2.Address.Zip);
+
+ connection.Stop();
+ }
}
}
View
5 SignalR.Tests/HubProxyTest.cs
@@ -3,6 +3,7 @@
using System.Threading;
using System.Threading.Tasks;
using Moq;
+using Newtonsoft.Json.Linq;
using SignalR.Client.Hubs;
using SignalR.Hosting.Memory;
using SignalR.Hubs;
@@ -83,7 +84,7 @@ public void InvokeEventRaisesEvent()
eventRaised = true;
});
- hubProxy.InvokeEvent("foo", new object[] { });
+ hubProxy.InvokeEvent("foo", new JToken[] { });
Assert.True(eventRaised);
}
@@ -100,7 +101,7 @@ public void InvokeEventRaisesEventWithData()
Assert.Equal(1, i);
});
- hubProxy.InvokeEvent("foo", new object[] { 1 });
+ hubProxy.InvokeEvent("foo", new[] { JToken.FromObject(1) });
Assert.True(eventRaised);
}
View
5 samples/SignalR.Hosting.AspNet.Samples/Hubs/DemoHub/DemoHub.cs
@@ -131,6 +131,11 @@ public void UnsupportedOverload(int x)
}
+ public void TestGuid()
+ {
+ Caller.TestGuid(new Guid());
+ }
+
public class Person
{
public string Name { get; set; }
Please sign in to comment.
Something went wrong with that request. Please try again.