【问题标题】:ASP.NET Core RC2 SignalR Hub Context outside request thread请求线程外的 ASP.NET Core RC2 SignalR Hub 上下文
【发布时间】:2016-09-16 00:54:34
【问题描述】:

我目前正在试用ASP.NET CoreRC2 版本,我遇到了SignalR 的问题。我需要能够在请求线程之外向客户端发送消息。

现在在完整的 .NET 框架中,您可以这样做:

var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
context.Clients.<SendMessage>()

但在ASP.NET 核心中没有GlobalHost

我发现了一个类似的问题: How to get SignalR Hub Context in a vNext Project?

第二个答案提供了一种在请求线程之外获取 hubcontext 的方法,但这在 ASP.NET Core 中也不起作用。

所以我的问题是:如何在 ASP.NET Core 的请求范围之外获取集线器上下文?

【问题讨论】:

标签: asp.net signalr asp.net-core asp.net-core-1.0 .net-core-rc2


【解决方案1】:

您必须从 Signalr Github 拉取当前的 github 版本 (在撰写本文时提交:b95ac7b

一旦你有了这个,并且已经加载了解决方案,或者将所有三个项目添加到你现有的解决方案中,你将需要在所有三个项目中更改 project.json。

Microsoft.AspNetCore.SignalR.Server - project.json

您将看到对每个程序集版本 1.1.0-* (RC3) 的引用。 将这些更改为当前的 RC2,直到您看到以下内容

"Microsoft.AspNetCore.DataProtection": "1.0.0",
"Microsoft.AspNetCore.Hosting.Abstractions": "1.0.0",
"Microsoft.AspNetCore.Http.Extensions": "1.0.0",
"Microsoft.Extensions.DependencyModel": "1.0.0",

现在保存文件,依赖项将更新。

MessagingInfrastructure project.json 文件执行相同操作,将任何 1.1.0-* 替换为 1.0.0

完成后,您可以将项目引用添加到 Microsoft.AspNetCore.SignalR.Server 的主项目

现在你已经加载了,打开你的 Startup.cs

ConfigureServices 方法中,添加:

 services.AddSignalR();

Configure方法里面添加:

 app.UseSignalR();

接下来,添加 using 语句并导入 Infrastructure 命名空间,如下所示:

using Microsoft.AspNetCore.SignalR.Infrastructure;

最后在 Startup.cs 中创建一个名为 ConnectionManager 的静态属性,如下所示:

public static IConnectionManager ConnectionManager;

最后在 Startup.cs 的 Configure 方法中添加一个 IServiceProvider 属性(需要导入 System 命名空间)。然后从这里加载 ConfigurationManager。

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider serviceProvider)
    {
        ConnectionManager = serviceProvider.GetService<IConnectionManager>();

现在,在您的集线器/其他任何地方,而不是使用 Globalhost,只需使用启动。例如:

IHubContext context = Startup.ConnectionManager.GetHubContext<SomeHub>();
context.Clients.All.someMethod();

【讨论】:

  • 有什么理由不只是将IConnectionManager 注入到服务中?
  • 工作完美;不过,不必对 project.json 搞砸(SignalR Core 处于较新的版本,但仍然是 alpha)
  • 嗨,您从哪里获得这些信息的?我找不到信号器核心的文档?
  • 请参阅 github.com/aspnet/SignalR/issues/498#issuecomment-304768866 Microsoft.AspNetCore.SignalR.Server 已弃用。此解决方案无法再应用
  • 是的。虽然这曾经是很好的信息,但现在它具有误导性,应该被删除。
【解决方案2】:

另一种可能性是将您的 HubContext 注入您的控制器,例如:

public VarDesignCommController(IHubContext<VarDesignHub> hubcontext)
{
    HubContext = hubcontext;
    ...
}

private IHubContext<VarDesignHub> HubContext
{
    get;
    set;
}

那你也可以调用

await this.HubContext.Clients.All.InvokeAsync("Completed", id);

但是你将在所有客户端上直接调用方法。

另一种可能性请参见Call SignalR Core Hub method from Controller

【讨论】:

    【解决方案3】:

    如果您想像在服务中一样在控制器之外使用集线器上下文,您可以试试这个。

    在您的 StartUp 课程中:

        private IHubContext<SomeHub> hubContext;
    

    在 ConfigureServices 方法中,将 hubContext 注入您的服务:

        services.AddScoped<ISomeService, SomeService>((factory) => {
            return new SomeService(hubContext);
        });
    

    在配置方法中:

        app.UseSignalR(routes =>
            {
                routes.MapHub<SomeHub>("/hubRoute");
            });
    
            hubContext = app.ApplicationServices.GetService<IHubContext<SomeHub>>();
    

    这解决了我无法从后端服务类调用客户端方法的问题。

    【讨论】:

    • 如果SomeService 有多个依赖项,而不仅仅是hubcontext,该怎么办?
    猜你喜欢
    • 2015-02-02
    • 2016-10-01
    • 1970-01-01
    • 2016-11-14
    • 2018-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-28
    相关资源
    最近更新 更多