我目前正在试用RC2
版ASP.NET Core
,我遇到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中的请求范围之外获取集线器上下文?
答案 0 :(得分:16)
您必须从以下位置提取当前的github版本:Signalr 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",
现在保存文件,依赖项将更新。
对消息传递和基础设施 project.json文件执行相同操作,将任何1.1.0- *替换为1.0.0
完成后,您可以向Microsoft.AspNetCore.SignalR.Server的主项目添加项目引用
现在已经加载了,打开 Startup.cs
在 ConfigureServices 方法内,添加:
services.AddSignalR();
在配置方法内添加:
app.UseSignalR();
接下来,添加using语句并导入Infrastructure命名空间,如下所示:
using Microsoft.AspNetCore.SignalR.Infrastructure;
最后在Startup.cs中创建一个名为ConnectionManager的静态属性,如下所示:
public static IConnectionManager ConnectionManager;
最后将一个IServiceProvider属性添加到Startup.cs中的Configure方法(需要导入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();
答案 1 :(得分:7)
另一种可能性是将HubContext注入控制器,如:
public VarDesignCommController(IHubContext<VarDesignHub> hubcontext)
{
HubContext = hubcontext;
...
}
private IHubContext<VarDesignHub> HubContext
{
get;
set;
}
然后你也可以打电话
await this.HubContext.Clients.All.InvokeAsync("Completed", id);
但是你会在所有客户端上直接调用方法。
答案 2 :(得分:3)
如果您想像服务中那样在控制器外部使用集线器上下文,可以尝试一下。
在您的StartUp类中:
private IHubContext<SomeHub> hubContext;
在ConfigureServices方法中,将hubContext注入您的服务中:
services.AddScoped<ISomeService, SomeService>((factory) => {
return new SomeService(hubContext);
});
在Configure方法中:
app.UseSignalR(routes =>
{
routes.MapHub<SomeHub>("/hubRoute");
});
hubContext = app.ApplicationServices.GetService<IHubContext<SomeHub>>();
这解决了我无法从后端服务类调用客户端方法的问题。