Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing strongly typed Hubs in SignalR

I've just updated some SignalR references and things have changed somewhat in order to allow for generically typed Hubs Hub<T>. In the existing examples and documentation such as at:

Server-Broadcast-with-Signalr

we have a static class holding references to clients via the following mechanisms:

public class StockTicker()
{
private readonly static Lazy<StockTicker> _instance = new Lazy<StockTicker>(
            () => new StockTicker(GlobalHost.ConnectionManager.GetHubContext<StockTickerHub>().Clients));

 IHubConnectionContext Clients {get;set;}

 private StockTicker(IHubConnectionContext clients)
        {
            Clients = clients;
        }
}

So a static reference is checked and if null it reaches out to :

GlobalHost.ConnectionManager.GetHubContext<StockTickerHub>().Clients

to create an instance and supply the clients via the constructor.

So this was how it used to work and indeed is how the url above has it. But now with Hub<T> there is a slight change required in the constructor:

 private StockTicker(IHubConnectionContext<dynamic> clients)
 {
   Clients = clients;
 }

Now my question is how can I extend this further such that my version of StockTicker can have a strongly typed property for clients of type x.

 IHubConnectionContext<StockTickerHub> Clients {get;set;}

 private StockTicker(IHubConnectionContext<dynamic> clients)
 {
   Clients = clients; // Fails, wont compile
 }

By maintaining strongly typed references I would be able to call strongly typed methods, etc.

like image 300
rism Avatar asked Aug 26 '14 06:08

rism


People also ask

How many concurrent connections can SignalR handle?

IIS on client operating systems has a limit of 10 concurrent connections. SignalR's connections are: Transient and frequently re-established. Not disposed immediately when no longer used.

Does SignalR need SSL?

If your SignalR application transmits sensitive information between the client and server, use SSL for the transport.

How do I send client specific messages using SignalR?

We change the BroadcastChartData() method to accept connectionId as an additional parameter. This way, we can find the client using the connectionId and send a message just to that client. Additionally, we add a new GetConnectionId() method, which returns the connectionId of the client.

Does SignalR require WebSockets?

ASP.NET Core SignalR is a library that simplifies adding real-time web functionality to apps. It uses WebSockets whenever possible.


2 Answers

There is now a new overload of GetHubContext that takes two generic parameters. The first is the Hub type like before, but the second generic parameter is TClient (which is the T in Hub<T>).

Assuming that StockTickerHub is defined as follows:

public class TypedDemoHub : Hub<IClient>

Then

GlobalHost.ConnectionManager.GetHubContext<StockTickerHub>().Clients

becomes

GlobalHost.ConnectionManager.GetHubContext<StockTickerHub, IClient>().Clients

The type returned by the new overload to GetHubContext would be IHubContext<IClient> and the Clients property would be IHubConnectionContext<IClient> instead of IHubConnectionContext<dynamic> or IHubConnectionContext<StockTickerHub>.

like image 136
halter73 Avatar answered Sep 20 '22 13:09

halter73


In .NET Core Web App you can inject strongly typed signalR hub context like this

public interface IClient
{
    Task ReceiveMessage(string message);
}

public class DevicesHub : Hub<IClient>
{
}

public class HomeController : ControllerBase
{
    private readonly IHubContext<DevicesHub, IClient> _devicesHub;

    public HomeController(IHubContext<DevicesHub, IClient> devicesHub)
    {
        _devicesHub = devicesHub;
    }       

    [HttpGet]
    public IEnumerable<string> Get()
    {
       _devicesHub.Clients
          .All
          .ReceiveMessage("Message from devices.");

       return new string[] { "value1", "value2" };
    }
}
like image 29
Stefan Varga Avatar answered Sep 21 '22 13:09

Stefan Varga