Permalink
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...
1 parent 6998c77 commit 50cefbba422a46adb1345bd4f22e49be7ecc52d2 @davidfowl davidfowl committed Jun 21, 2012
@@ -1,12 +1,13 @@
using System.Collections.Generic;
+using Newtonsoft.Json.Linq;
namespace SignalR.Client.Hubs
{
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; }
}
}
@@ -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))
@@ -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>();
}
}
}
@@ -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
@@ -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,13 +148,79 @@ public void ChangeHubUrl()
Assert.NotNull(id);
wh.Set();
});
-
+
connection.Start(host).Wait();
hub.Invoke("DynamicTask").Wait();
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();
+ }
}
}
@@ -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);
}
@@ -131,6 +131,11 @@ public void UnsupportedOverload(int x)
}
+ public void TestGuid()
+ {
+ Caller.TestGuid(new Guid());
+ }
+
public class Person
{
public string Name { get; set; }

0 comments on commit 50cefbb

Please sign in to comment.