C# ASP.NET核心信号器从任何位置访问集线器方法
如果我在这个问题上花了很多时间,我发现了很多不同的策略,但没有一个对我有效。(当然,这段代码只是概念的证明。) 我使用Asp.net core 2.1(在.net Framwork 4.7.2上)进行了以下设置: 我制作了一个信号器集线器,它有一种发送号码的方法:C# ASP.NET核心信号器从任何位置访问集线器方法,c#,asp.net-core,dependency-injection,asp.net-core-signalr,C#,Asp.net Core,Dependency Injection,Asp.net Core Signalr,如果我在这个问题上花了很多时间,我发现了很多不同的策略,但没有一个对我有效。(当然,这段代码只是概念的证明。) 我使用Asp.net core 2.1(在.net Framwork 4.7.2上)进行了以下设置: 我制作了一个信号器集线器,它有一种发送号码的方法: using System.Threading.Tasks; using Microsoft.AspNetCore.SignalR; namespace TestRandomNumberSignalR { public cl
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
namespace TestRandomNumberSignalR
{
public class TestHub : Hub
{
public async Task SendRandomNumber(int number)
{
await Clients.All.SendAsync("ReceiveRandomBumber", number);
}
}
}
我还创建了一个类,每3秒更新一个随机数,并将其添加为单例:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace TestRandomNumberSignalR
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(new UpdateRandomNumber());
services.AddSignalR();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
app.UseSignalR(routes =>
{
routes.MapHub<TestHub>("/testHub");
});
}
}
}
现在,在这个类中(正如我在评论中所写的),我想使用signar发送新的随机数。只有如何在那里获取中心上下文
我还希望能够从控制器中访问类上的Stop()方法,如何访问该方法
我现在知道这是一个讨论得很好的话题,但我仍然找不到一个可行的解决方案。希望你能帮助我
编辑
问题1
虽然随机循环现在开始了(多亏了rasharasha),但仍然存在一些问题。我现在无法将正确的UpdateAndomNumber注入控制器。假设我希望能够停止调用UpdateRandomNumber.stop()方法的循环,那么如何将UpdateRandomNumber单例注入控制器。我尝试创建一个界面:
public interface IUpdateRandomNumber
{
void Stop();
}
services.AddSingleton<IUpdateRandomNumber>(provider =>
{
var hubContext = provider.GetService<IHubContext<TestHub>>();
var updateRandomNumber = new UpdateRandomNumber(hubContext);
return updateRandomNumber;
});
更改RandomNumber方法以实现此目的:
public class UpdateRandomNumber : IUpdateRandomNumber
{
private bool _continue = true;
private IHubContext<TestHub> testHub;
public UpdateRandomNumber(IHubContext<TestHub> testHub)
{
this.testHub = testHub;
var task = new Task(() => RandomNumberLoop(),
TaskCreationOptions.LongRunning);
task.Start();
}
private void RandomNumberLoop()
{
Random r = new Random();
while (_continue)
{
Thread.Sleep(3000);
int number = r.Next(0, 100);
Console.WriteLine("The random number is now " + number);
// Send new random number to connected subscribers here
// Something like TestHub.SendRandomNumber(number);
}
}
public void Stop()
{
_continue = false;
}
}
但是,此实现将防止循环再次启动。那么如何从控制器访问rondomnumber单例呢
问题2
现在,我可以从UpdateRandomNumber类调用:
testHub.Clients.All.SendAsync("ReceiveRandomBumber", number);
但是为什么我要在testhub中创建该方法:
public async Task SendRandomNumber(int number)
{
await Clients.All.SendAsync("ReceiveRandomBumber", number);
}
在hub中创建方法并直接调用它们会更方便。可以这样做吗?您可以使用构造函数注入将TestHub注入控制器。因为它已经在DI容器中注册
public class UpdateRandomNumber
{
private bool _continue = true;
private IHubContext<TestHub> testHub;
private Task randomNumberTask;
public UpdateRandomNumber(IHubContext<TestHub> testHub)
{
this.testHub=testHub;
randomNumberTask = new Task(() => RandomNumberLoop(),
TaskCreationOptions.LongRunning);
randomNumberTask.Start();
}
private async void RandomNumberLoop()
{
Random r = new Random();
while (_continue)
{
Thread.Sleep(3000);
int number = r.Next(0, 100);
Console.WriteLine("The random number is now " + number);
// Send new random number to connected subscribers here
await testHub.Clients.All.SendAsync($"ReceiveRandomNumber", number);
}
}
public void Stop()
{
_continue = false;
}
}
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddSingleton(provider =>
{
var hubContext = provider.GetService<IHubContext<TestHub>>();
var updateRandomNumber = new UpdateRandomNumber(hubContext);
return updateRandomNumber;
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
var updateRandonNumber = app.ApplicationServices.GetService<UpdateRandomNumber>();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
app.UseSignalR(routes =>
{
routes.MapHub<TestHub>("/testHub");
});
}
}
公共类更新域编号
{
private bool _continue=true;
私有IHubContext测试中心;
私有任务随机数任务;
公共更新域编号(IHubContext testHub)
{
this.testHub=testHub;
randomNumberTask=新任务(()=>RandomNumberLoop(),
TaskCreationOptions.LongRunning);
randomNumberTask.Start();
}
私有异步void RandomNumberLoop()
{
随机r=新随机();
while(_continue)
{
睡眠(3000);
整数=r.Next(0,100);
Console.WriteLine(“随机数现在是”+数字);
//在此处向已连接的订户发送新的随机数
等待testHub.Clients.All.SendAsync($“ReceiveRandomNumber”,number);
}
}
公共停车场()
{
_continue=false;
}
}
公营创业
{
公共启动(IConfiguration配置)
{
配置=配置;
}
公共IConfiguration配置{get;}
//此方法由运行时调用。请使用此方法将服务添加到容器中。
public void配置服务(IServiceCollection服务)
{
services.AddSignalR();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddSingleton(提供者=>
{
var hubContext=provider.GetService();
var updateRandomNumber=新的updateRandomNumber(hubContext);
返回updateRandomNumber;
});
}
//此方法由运行时调用。请使用此方法配置HTTP请求管道。
公共无效配置(IApplicationBuilder应用程序,IHostingEnvironment环境)
{
var updateRandonNumber=app.ApplicationServices.GetService();
if(env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
app.usesigner(路由=>
{
routes.MapHub(“/testHub”);
});
}
}
您可以使用构造函数注入将TestHub注入控制器。因为它已经在DI容器中注册
public class UpdateRandomNumber
{
private bool _continue = true;
private IHubContext<TestHub> testHub;
private Task randomNumberTask;
public UpdateRandomNumber(IHubContext<TestHub> testHub)
{
this.testHub=testHub;
randomNumberTask = new Task(() => RandomNumberLoop(),
TaskCreationOptions.LongRunning);
randomNumberTask.Start();
}
private async void RandomNumberLoop()
{
Random r = new Random();
while (_continue)
{
Thread.Sleep(3000);
int number = r.Next(0, 100);
Console.WriteLine("The random number is now " + number);
// Send new random number to connected subscribers here
await testHub.Clients.All.SendAsync($"ReceiveRandomNumber", number);
}
}
public void Stop()
{
_continue = false;
}
}
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddSingleton(provider =>
{
var hubContext = provider.GetService<IHubContext<TestHub>>();
var updateRandomNumber = new UpdateRandomNumber(hubContext);
return updateRandomNumber;
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
var updateRandonNumber = app.ApplicationServices.GetService<UpdateRandomNumber>();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
app.UseSignalR(routes =>
{
routes.MapHub<TestHub>("/testHub");
});
}
}
公共类更新域编号
{
private bool _continue=true;
私有IHubContext测试中心;
私有任务随机数任务;
公共更新域编号(IHubContext testHub)
{
this.testHub=testHub;
randomNumberTask=新任务(()=>RandomNumberLoop(),
TaskCreationOptions.LongRunning);
randomNumberTask.Start();
}
私有异步void RandomNumberLoop()
{
随机r=新随机();
while(_continue)
{
睡眠(3000);
整数=r.Next(0,100);
Console.WriteLine(“随机数现在是”+数字);
//在此处向已连接的订户发送新的随机数
等待testHub.Clients.All.SendAsync($“ReceiveRandomNumber”,number);
}
}
公共停车场()
{
_continue=false;
}
}
公营创业
{
公共启动(IConfiguration配置)
{
配置=配置;
}
公共IConfiguration配置{get;}
//此方法由运行时调用。请使用此方法将服务添加到容器中。
public void配置服务(IServiceCollection服务)
{
services.AddSignalR();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddSingleton(提供者=>
{
var hubContext=provider.GetService();
var updateRandomNumber=新的updateRandomNumber(hubContext);
返回updateRandomNumber;
});
}
//此方法由运行时调用。请使用此方法配置HTTP请求管道。
公共无效配置(IApplicationBuilder应用程序,IHostingEnvironment环境)
{
var updateRandonNumber=app.ApplicationServices.GetService();
if(env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
美联社
public class UpdateRandomNumber
{
private bool _continue = true;
private IHubContext<TestHub> testHub;
private Task randomNumberTask;
public UpdateRandomNumber(IHubContext<TestHub> testHub)
{
this.testHub=testHub;
randomNumberTask = new Task(() => RandomNumberLoop(),
TaskCreationOptions.LongRunning);
randomNumberTask.Start();
}
private async void RandomNumberLoop()
{
Random r = new Random();
while (_continue)
{
Thread.Sleep(3000);
int number = r.Next(0, 100);
Console.WriteLine("The random number is now " + number);
// Send new random number to connected subscribers here
await testHub.Clients.All.SendAsync($"ReceiveRandomNumber", number);
}
}
public void Stop()
{
_continue = false;
}
}
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddSingleton(provider =>
{
var hubContext = provider.GetService<IHubContext<TestHub>>();
var updateRandomNumber = new UpdateRandomNumber(hubContext);
return updateRandomNumber;
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
var updateRandonNumber = app.ApplicationServices.GetService<UpdateRandomNumber>();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
app.UseSignalR(routes =>
{
routes.MapHub<TestHub>("/testHub");
});
}
}