在SignalR中传递强类型的集线器

ris*_*ism 12 c# asp.net signalr signalr-hub

我刚刚更新了一些SignalR引用,但为了允许一般类型的Hub,情况有所改变Hub<T>.在现有的示例和文档中,例如:

服务器广播与 - Signalr

我们有一个静态类,通过以下机制保存对客户端的引用:

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;
        }
}
Run Code Online (Sandbox Code Playgroud)

因此检查静态引用,如果为null则它会到达:

GlobalHost.ConnectionManager.GetHubContext<StockTickerHub>().Clients
Run Code Online (Sandbox Code Playgroud)

创建实例并通过构造函数提供客户端.

所以这就是它以前的工作方式,而且确实是上面的网址是如何工作的.但现在Hub<T>构造函数需要稍微改变:

 private StockTicker(IHubConnectionContext<dynamic> clients)
 {
   Clients = clients;
 }
Run Code Online (Sandbox Code Playgroud)

现在我的问题是如何进一步扩展这一点,以便我的StockTicker版本可以为x类型的客户端提供强类型属性.

 IHubConnectionContext<StockTickerHub> Clients {get;set;}

 private StockTicker(IHubConnectionContext<dynamic> clients)
 {
   Clients = clients; // Fails, wont compile
 }
Run Code Online (Sandbox Code Playgroud)

通过维护强类型引用,我可以调用强类型方法等.

hal*_*r73 27

现在有一个新的GetHubContext重载,它带有两个通用参数.第一个是像之前一样的Hub类型,但第二个通用参数是TClient(它是T in Hub<T>).

假设StockTickerHub定义如下:

public class TypedDemoHub : Hub<IClient>
Run Code Online (Sandbox Code Playgroud)

然后

GlobalHost.ConnectionManager.GetHubContext<StockTickerHub>().Clients
Run Code Online (Sandbox Code Playgroud)

GlobalHost.ConnectionManager.GetHubContext<StockTickerHub, IClient>().Clients
Run Code Online (Sandbox Code Playgroud)

GetHubContext的新重载返回的类型将是IHubContext<IClient>,而Clients属性将IHubConnectionContext<IClient>代替IHubConnectionContext<dynamic>IHubConnectionContext<StockTickerHub>.


Ste*_*rga 8

.NET Core Web App 中,您可以 像这样注入强类型的 signalR 集线器上下文

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" };
    }
}
Run Code Online (Sandbox Code Playgroud)