C# 将集线器上下文传递给非控制器类
我正在尝试使用SignalR向服务器中的客户端发送消息 我试图在一个不是控制器的类中实现这一点。我是这样创业的:C# 将集线器上下文传递给非控制器类,c#,signalr,C#,Signalr,我正在尝试使用SignalR向服务器中的客户端发送消息 我试图在一个不是控制器的类中实现这一点。我是这样创业的: public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method
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.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.Configure<ConfigurationModel>(Configuration.GetSection("configurationModel"));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddSignalR();
}
// 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();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc();
app.UseSignalR(routes => { routes.MapHub<MoveViewHub>("/movehub"); });
}
}
这是RfidClass:
private IHubContext<MoveViewHub> hubContext;
public RfidClass(IHubContext<MoveViewHub> hubContext)
{
this.hubContext = hubContext;
}
public void sas()
{
Start();
}
private void Start()
{
try
{
hubContext.Clients.Others.SendAsync("ReceivedFromServer", "You are connected");
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
私有IHubContext-hubContext;
公共RfidClass(IHubContext-hubContext)
{
this.hubContext=hubContext;
}
公共空间
{
Start();
}
私有void Start()
{
尝试
{
hubContext.Clients.Others.SendAsync(“ReceivedFromServer”,“您已连接”);
}
捕获(例外e)
{
控制台写入线(e);
投掷;
}
}
如何使其正确?您需要通过.NET Core DI将
IServiceProvider
注入您的Hub
(就像注入标准控制器一样,通过构造函数注入):
然后你可以这样做:
public override Task OnConnectedAsync()
{
Console.WriteLine("Client has connected");
// you need to inject service provider to your hub, then get hub context from
// registered services
using (var scope = this.provider.CreateScope())
{
// get instance of hub from service provider
var scopedServices = scope.ServiceProvider;
var hub = scopedServices.GetRequiredService<IHubContext<MoveViewHub>>
// pass hub to class constructor
RfidClass rfidClass = new RfidClass(hub)
rfidClass.sas();
RfidClass.SendTagNumber += ReceiveTagNumber;
}
System.Diagnostics.Process.Start(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Notepad++", @"notepad++.exe"));
return base.OnConnectedAsync();
}
然后在启动
类中注册该服务:
services.AddScoped<ISignalRService, SignalRService>();
您不需要像
RfidClass
这样做,您需要通过.NET Core DI将IServiceProvider
注入到您的Hub
中(如注入标准控制器,通过构造函数注入):
然后你可以这样做:
public override Task OnConnectedAsync()
{
Console.WriteLine("Client has connected");
// you need to inject service provider to your hub, then get hub context from
// registered services
using (var scope = this.provider.CreateScope())
{
// get instance of hub from service provider
var scopedServices = scope.ServiceProvider;
var hub = scopedServices.GetRequiredService<IHubContext<MoveViewHub>>
// pass hub to class constructor
RfidClass rfidClass = new RfidClass(hub)
rfidClass.sas();
RfidClass.SendTagNumber += ReceiveTagNumber;
}
System.Diagnostics.Process.Start(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Notepad++", @"notepad++.exe"));
return base.OnConnectedAsync();
}
然后在启动
类中注册该服务:
services.AddScoped<ISignalRService, SignalRService>();
您不需要像
RfidClass
这样做,您可以添加services.AddDbContext来配置服务并进行检查,以便可以插入您的数据库上下文。我需要signer先生提供的hubcontext。不是数据库上下文。您能告诉我们如何调用您的RfidClass
?如果控制器调用了RfidClass
,请解释它是如何工作的?一旦Rfid类被实例化,我只希望它启动,然后发送一条消息,说明您已连接。我在OnConnectedAsync上调用它。检查我的答案@ibanez1408您能添加services.AddDbContext到ConfigureServices并检查,以便可以插入您的DB上下文。我需要signer先生提供的hubcontext。不是数据库上下文。您能告诉我们如何调用您的RfidClass
?如果控制器调用了RfidClass
,请解释它是如何工作的?一旦Rfid类被实例化,我只希望它启动,然后发送一条消息,说明您已连接。我在OnConnectedAsync上调用它。检查我的答案@Ibanez1408Sir,当你说…然后从注册服务获取中心上下文时,你是如何做到的?你能给我举个例子吗。谢谢。我粘贴了您代码片段中的解决方案。它不工作吗?您需要在MovieViewHub
中调用IServiceProvider
您想在RfidClass
中使用HubContext
,或者只需以正确的方式使用SignalR
?谢谢先生。成功了。先生,当你说……然后从注册服务获取中心上下文时,你是如何做到的?你能给我举个例子吗。谢谢。我粘贴了您代码片段中的解决方案。它不工作吗?您需要在MovieViewHub
中调用IServiceProvider
您想在RfidClass
中使用HubContext
,或者只需以正确的方式使用SignalR
?谢谢先生。这就成功了。
// you need to make your own class and interface and inject hub context
public interface ISignalRService
{
Task SendMessageToAll(string message);
}
public class SignalRService : ISignalRService
{
private readonly IHubContext<YourHub> hubContext;
public SignalRService (IHubContext<NotificationHub> hubContext)
{
this.hubContext = hubContext;
}
public async Task SendMessageToAll(string message)
{
await this.hubContext.Clients.All.SendAsync("ReciveMessage", message);
}
}
services.AddScoped<ISignalRService, SignalRService>();
private readonly ISignalRService notificationService;
public SomeController(ISignalRService notificationService)
{
this.notificationService = notificationService;
}
[HttpGet]
public async Task<IActionResult> Send()
{
await this.notificationService.SendMessageToAll("message");
return Ok();
}