![](/img/trans.png)
[英]Hub method from client is not invoking in ASP.NET Core SignalR
[英]Using Hub from separate class in ASP.NET Core 3
我正在开发一个程序,我从 SignalR 接收数据,执行处理,然后在处理完成后将 SignalR 消息发送回客户端。 我找到了一些关于如何做到这一点的资源,但我不太清楚如何在我的项目中实现它。
这是我的代码的样子:
自举
public static void Main(string[] args)
{
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
List<ISystem> systems = new List<ISystem>
{
new FirstProcessingSystem(),
new SecondProcessingSystem(),
};
Processor processor = new Processor(
cancellationToken: cancellationTokenSource.Token,
systems: systems);
processor.Start();
CreateHostBuilder(args).Build().Run();
cancellationTokenSource.Cancel();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<TestHub>("/testHub");
});
}
}
测试集线器.cs
public class TestHub : Hub
{
public async Task DoStuff(Work work)
{
FirstProcessingSystem.ItemsToProcess.Add(work);
}
}
工作.cs
public class Work
{
public readonly string ConnectionId;
public readonly string Data;
public Work(string connectionId, string data)
{
ConnectionId = connectionId;
Data = data;
}
}
处理器.cs
public class Processor
{
readonly CancellationToken CancellationToken;
readonly List<ISystem> Systems;
public Processor(
CancellationToken cancellationToken,
List<ISystem> systems)
{
CancellationToken = cancellationToken;
Systems = systems;
}
public void Start()
{
Task.Run(() =>
{
while (!CancellationToken.IsCancellationRequested)
{
foreach (var s in Systems)
s.Process();
}
});
}
}
系统
public interface ISystem
{
void Process();
}
public class FirstProcessingSystem : ISystem
{
public static ConcurrentBag<Work> ItemsToProcess = new ConcurrentBag<Work>();
public void Process()
{
while (!ItemsToProcess.IsEmpty)
{
Work work;
if (ItemsToProcess.TryTake(out work))
{
// Do things...
SecondProcessingSystem.ItemsToProcess.Add(work);
}
}
}
}
public class SecondProcessingSystem : ISystem
{
public static ConcurrentBag<Work> ItemsToProcess = new ConcurrentBag<Work>();
public void Process()
{
while (!ItemsToProcess.IsEmpty)
{
Work work;
if (ItemsToProcess.TryTake(out work))
{
// Do more things...
// Hub.Send(work.ConnectionId, "Finished");
}
}
}
}
我知道我可以在 Hub 中执行处理,然后发回“已完成”调用,但我想将我的处理与入站消息分离,这样我可以在需要时添加更多ISystems
。
有人可以请这个吗? (另外,如果有人有更好的方法来构建我的程序,我也会感谢反馈)
aspnet有一个非常强大的依赖注入系统,你为什么不用呢? 通过在没有依赖注入的情况下创建工作服务,您将很难使用 aspnet 提供的任何东西。
由于您的“处理系统”似乎是长时间运行的服务,您通常会让它们实现IHostedService
,然后创建一个通用服务启动器(取自此处):
public class BackgroundServiceStarter<T> : IHostedService where T : IHostedService
{
readonly T _backgroundService;
public BackgroundServiceStarter(T backgroundService)
{
_backgroundService = backgroundService;
}
public Task StartAsync(CancellationToken cancellationToken)
{
return _backgroundService.StartAsync(cancellationToken);
}
public Task StopAsync(CancellationToken cancellationToken)
{
return _backgroundService.StopAsync(cancellationToken);
}
}
然后将它们注册到ConfigureServices
的 DI 容器中:
// make the classes injectable
services.AddSingleton<FirstProcessingSystem>();
services.AddSingleton<SecondProcessingSystem>();
// start them up
services.AddHostedService<BackgroundServiceStarter<FirstProcessingSystem>>();
services.AddHostedService<BackgroundServiceStarter<SecondProcessingSystem>>();
现在您已正确设置所有内容,您可以使用IHubContext<TestHub> context
在需要它的任何 class 的构造函数参数中简单地注入对 signalR 集线器的引用(如您发布的一些链接中所述)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.