SignalR with orleans 如何将 SignalR 从启动传递到 grain
SignalR with orleans how to pass SignalR from startup to grain
我对 orleans 还很陌生,我正试图用谷物等来掌握一切。
我得到的是,在我的 startup.cs 文件中,我添加了这样的 SignalR
public IServiceProvider ConfigureServices(IServiceCollection services)
{
Program.WriteConsole("Adding singletons");
services
.AddSingleton(achievementManager)
.AddMvc();
services.AddSingleton(SignalRClient);
return services.BuildServiceProvider();
}
到目前为止一切都很好,我可以启动我的 host/application 并且它应该连接到 SignalR。但是我无法解决的问题是如何将其归结为我的谷物?如果我有一个控制器,我会在启动时简单地将它发送到构造函数中,但是我如何用谷物来做到这一点?或者我什至可以这样做。任何指导表示赞赏。
在谷物中然后我想做这样的事情
[StatelessWorker]
[Reentrant]
public class NotifierGrain : Grain, INotifierGrain
{
private HubConnection SignalRClient { get; }
public NotifierGrain(HubConnection signalRClient)
{
SignalRClient = signalRClient;
SignalRClient.SendAsync(Methods.RegisterService, Constants.ServiceName);
}
public Task NotifyClients(object message, MessageType type)
{
var registerUserNotification = (RegisterUserNotificationModel)message;
SignalRClient.SendAsync(Methods.RegisterUserToMultipleGroups, registerUserNotification.UserId, registerUserNotification.InfoIds);
}
return Task.CompletedTask;
}
然后我尝试像这样从另一个 grain 调用 Notify 方法
var notifier = GrainFactory.GetGrain<INotifierGrain>(Constants.NotifierGrain);
await notifier.NotifyClients(notification, MessageType.RegisterUser);
但是尝试这样做最终会出现这样的错误
InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.SignalR.Client.HubConnection' while attempting to activate 'User.Implementation.Grains.NotifierGrain'.
Orleans 支持构造函数注入,因此您可以将 SignalRClient
注入到您的 grain 构造函数中。在您的代码中,您已经使用 services.AddSingleton(SignalRClient)
正确注册了客户端,因此我将重点介绍如何将类型注入到您的 grain 中。
我不知道 SignalR 客户端对象是什么类型,但在这个例子中我假设类型是“SignalRClient
”:
[StatelessWorker]
[Reentrant]
public class NotifierGrain : Grain, INotifierGrain
{
private readonly SignalRClient signalRClient;
public NotifierGrain(SignalRClient signalRClient)
{
this.signalRClient = signalRClient;
}
public async Task NotifyClients(object message, MessageType type)
{
var registerUserNotification = (RegisterUserNotificationModel)message;
await this.signalRClient.SendAsync(
MessageMethods.RegisterUserToMultipleGroups,
registerUserNotification.UserId,
registerUserNotification.infoIds);
}
}
取决于您打算如何使用 SignalR Server,如果您要使用 Microsoft Orleans 托管 SignalR 服务器,您肯定需要有背板来处理 Orleans 集群通信。
您可以使用 SignalR Orleans,它已经为您准备好了一切:)
此外,如果您需要用于前端的反应式 SignalR 库,您可以使用 Sketch7 SignalR Client
PS我是这两个库的作者之一。
我对 orleans 还很陌生,我正试图用谷物等来掌握一切。
我得到的是,在我的 startup.cs 文件中,我添加了这样的 SignalR
public IServiceProvider ConfigureServices(IServiceCollection services)
{
Program.WriteConsole("Adding singletons");
services
.AddSingleton(achievementManager)
.AddMvc();
services.AddSingleton(SignalRClient);
return services.BuildServiceProvider();
}
到目前为止一切都很好,我可以启动我的 host/application 并且它应该连接到 SignalR。但是我无法解决的问题是如何将其归结为我的谷物?如果我有一个控制器,我会在启动时简单地将它发送到构造函数中,但是我如何用谷物来做到这一点?或者我什至可以这样做。任何指导表示赞赏。
在谷物中然后我想做这样的事情
[StatelessWorker]
[Reentrant]
public class NotifierGrain : Grain, INotifierGrain
{
private HubConnection SignalRClient { get; }
public NotifierGrain(HubConnection signalRClient)
{
SignalRClient = signalRClient;
SignalRClient.SendAsync(Methods.RegisterService, Constants.ServiceName);
}
public Task NotifyClients(object message, MessageType type)
{
var registerUserNotification = (RegisterUserNotificationModel)message;
SignalRClient.SendAsync(Methods.RegisterUserToMultipleGroups, registerUserNotification.UserId, registerUserNotification.InfoIds);
}
return Task.CompletedTask;
}
然后我尝试像这样从另一个 grain 调用 Notify 方法
var notifier = GrainFactory.GetGrain<INotifierGrain>(Constants.NotifierGrain);
await notifier.NotifyClients(notification, MessageType.RegisterUser);
但是尝试这样做最终会出现这样的错误
InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.SignalR.Client.HubConnection' while attempting to activate 'User.Implementation.Grains.NotifierGrain'.
Orleans 支持构造函数注入,因此您可以将 SignalRClient
注入到您的 grain 构造函数中。在您的代码中,您已经使用 services.AddSingleton(SignalRClient)
正确注册了客户端,因此我将重点介绍如何将类型注入到您的 grain 中。
我不知道 SignalR 客户端对象是什么类型,但在这个例子中我假设类型是“SignalRClient
”:
[StatelessWorker]
[Reentrant]
public class NotifierGrain : Grain, INotifierGrain
{
private readonly SignalRClient signalRClient;
public NotifierGrain(SignalRClient signalRClient)
{
this.signalRClient = signalRClient;
}
public async Task NotifyClients(object message, MessageType type)
{
var registerUserNotification = (RegisterUserNotificationModel)message;
await this.signalRClient.SendAsync(
MessageMethods.RegisterUserToMultipleGroups,
registerUserNotification.UserId,
registerUserNotification.infoIds);
}
}
取决于您打算如何使用 SignalR Server,如果您要使用 Microsoft Orleans 托管 SignalR 服务器,您肯定需要有背板来处理 Orleans 集群通信。
您可以使用 SignalR Orleans,它已经为您准备好了一切:)
此外,如果您需要用于前端的反应式 SignalR 库,您可以使用 Sketch7 SignalR Client
PS我是这两个库的作者之一。