SignalR Hub中的事件处理程序将多个消息发送到客户端

时间:2019-11-14 06:20:26

标签: c# signalr

我有一个SignalR Class,其中包含我的SignalR服务器从启动服务器到提供命令之类的所有逻辑。对于扩展到Presenter Class的模块,我也有一个SignalR Class,所以我可以从那个模块开始,也可以在那里单独启动。我现在关心的是如何将某种命令发送到Hub Class的子项SignalR Class

这里发生的是,如果我收到来自客户的对SendCommand的呼叫,我会将其传递给Presenter Class进行进一步处理,然后需要返回到{{1 }}之后的Hub Class的子代。

我最初的想法是在Signal Class的根上创建一个Static EventHandler,然后在其SignalR Class子代的构造函数中实现。但是,事实证明这不是一个好主意,因为由于服务器的EventHandler,客户端正在接收重复的消息,因为我已经阅读到“ SignalR为每个请求创建一个新的中心实例” 。还有其他可行的方法可以以不同的实现方式来完成我想要的事情。

以下是基于我的模式的示例代码:

  

SignalR.cs

Hub Class
  

ModulePresenter.cs

[assembly: OwinStartup(typeof(MY_NAMESPACE_HERE.SignalR.Startup))]
public class SignalR
{
    private static event EventHandler<CommandCompletedEventArgs> CommandCompleted;
    public static void OnCommandCompleted(CommandCompletedEventArgs e)
    {
        CommandCompleted?.Invoke(typeof(SignalR), e);
    }
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCors(CorsOptions.AllowAll);
            app.MapSignalR();
        }
    }
    public class MyHub : Hub
    {
        public static event EventHandler<CommandSentEventArgs> CommandSent;
        public MyHub()
        {
            // this -= proved to not be effective as there's multiple instance of the MyHub class
            // one after the other, and is not being disposed of
            CommandCompleted -= MyHub_CommandCompleted;
            CommandCompleted += MyHub_CommandCompleted;
        }
        private static void MyHub_CommandCompleted(object sender, CommandCompletedEventArgs e)
        {
            // the client receives multiple messages from this command due to the instance multiplying per request together with event assignment duplicates
            Clients.Client(e.ConnectionId).BroadcastResponse(e.Response);
        }
        protected void OnCommandSent(CommandSentEventArgs e)
        {
            CommandSent?.Invoke(this, e);
        }
        public override Task OnConnected()
        {
            return base.OnConnected();
        }
        public override Task OnDisconnected(bool stopCalled)
        {
            return base.OnDisconnected(stopCalled);
        }
        public void SendCommand(string commandJson)
        {
            var command = Utilities.DeserializeJson<Command>(commandJson);
            switch (command.key)
            {
                case "request-token":
                    OnCommandSent(new CommandSentEventArgs(ConnectionId, command));
                    break;
                default:
               Clients.Client(Context.ConnectionId).addMessage("Unregistered command received: ", commandJson);
                    break;
            }
        }
    }
}

0 个答案:

没有答案