【问题标题】:SignalR with orleans how to pass SignalR from startup to grainSignalR with orleans 如何将 SignalR 从启动传递到grain
【发布时间】:2019-07-16 08:07:06
【问题描述】:

我对奥尔良很陌生,并试图用谷物等掌握一切。

我得到的是在我的 startup.cs 文件中我像这样添加 SignalR

public IServiceProvider ConfigureServices(IServiceCollection services)
    {

        Program.WriteConsole("Adding singletons");
        services
            .AddSingleton(achievementManager)
            .AddMvc();
        services.AddSingleton(SignalRClient);

        return services.BuildServiceProvider();
    }

到目前为止一切都很好,我可以启动我的主机/应用程序,它应该连接到 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;
    }

然后我尝试像这样从另一个谷物调用 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'.

【问题讨论】:

    标签: dependency-injection signalr orleans


    【解决方案1】:

    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);
        }
    }
    

    【讨论】:

    • 我正在寻找这样的东西!如果您查看我的编辑,这就是我现在尝试实现此功能的方式,而 SignalRClient 是 HubConnection。但是当另一个谷物试图在编辑中调用它时,我得到一个错误,我也编辑了。你知道为什么吗?
    • 您没有在 DI 容器中注册 HubConnection,因此您无法注入它。您必须使用要注入的相同类型注册客户端。在调用 AddSingleton(T value) 时,可以显式指定它注册为 (T) 的类型,因此需要将其注册为 HubConnection。 AddSingleton&lt;HubConnection&gt;(SignalRClient)
    【解决方案2】:

    取决于您考虑如何使用 SignalR 服务器,如果您要使用 Microsoft Orleans 托管您的 SignalR 服务器,那么您肯定需要有背板来处理 Orleans 集群通信。

    您可以使用SignalR Orleans,它为您完成了所有开箱即用的工作:)

    另外,如果您需要前端的反应式 SignalR 库,您可以使用Sketch7 SignalR Client

    PS 我是这两个库的作者之一。

    【讨论】:

      猜你喜欢
      • 2016-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多