4
votes

I'm getting started with SignalR (.Net client), and in the examples I've seen so far they create the connection, then create the hub proxy(s), then start the connection, e.g.:-

var hubConnection = new HubConnection("http://localhost:8080/");

var fooProxy = hubConnection.CreateHubProxy("FooHub");
var barProxy = hubConnection.CreateHubProxy("BarHub");

hubConnection.Start().Wait();

// The proxies can now be used

My server is going to consist of several hubs (mainly providing request-response style operations to clients), but it doesn't feel right that the client should create all the proxies it might need during startup, then pass them around to be used by other classes in the client.

Is it possible to create a hub proxy only when it's needed (e.g. in a method) then dispose of it when finished with? (I've tried this but SignalR won't let you create a hub proxy once the connection has started). Or is it "expensive" to create a hub proxy, hence why it's all done "up front"?

If I'm stuck with creating the proxies in this way, what would be a good way of exposing them to the rest of the client code? Some kind of singleton factory?

1

1 Answers

7
votes

The error message is quite clear - you can't create proxies after the connection is established. At the time that the connection is established, SignalR needs to know which hubs you're interested in. From the documentation:

For JavaScript clients you have to register at least one event handler before calling the Start method to establish the connection. This is not necessary for .NET clients. For JavaScript clients, the generated proxy code automatically creates proxies for all Hubs that exist on the server, and registering a handler is how you indicate which Hubs your client intends to use. But for a .NET client you create Hub proxies manually, so SignalR assumes that you will be using any Hub that you create a proxy for.

(I believe that this basically comes down to how they've designed their protocol behind the scenes, and that it's basically that when the connection is established, the first information sent is about which hubs are being used, and after that the connection is just used for transferring the actual method call information, but I'm by no means an expert)

Is it possible to create a hub proxy only when it's needed (e.g. in a method) then dispose of it when finished with?

Not unless you want to establish a separate HubConnection object also. Depends on how many connections you want each client to create.

Or is it "expensive" to create a hub proxy, hence why it's all done "up front"?

The proxies are not expensive, but starting the HubConnection is. Having decided that they'll have you create the proxies before starting the connection, then obviously every example you'll find does so.

If I'm stuck with creating the proxies in this way, what would be a good way of exposing them to the rest of the client code? Some kind of singleton factory?

Whatever you're most comfortable with - you could store them in static fields in a static class (the closest C# comes to global variables) if you so wanted. For me, anything other than toy projects tends to always have a Dependency Injection component, so for me I'd create the proxies early on and just put them into the DI container. They can safely be stored as singletons in the container since:

The proxy object is thread-safe. In fact, if you call HubConnection.CreateHubProxy multiple times with the same hubName, you get the same cached IHubProxy object.