SignalR calling client method from outside hub using GlobalHost.ConnectionManager.GetHubContext doesn't work. But calling from within the hub does

本小妞迷上赌 提交于 2019-11-27 17:51:29
Yusuf Uzun

I came across with same issue couple days ago. That took my 2 days to find solution and resolve it. After some serious investigate the problems root cause was the signalr dependency resolver that I set customly.

At the end I found this link and that was saying this:

Replacing the DependencyResolver

You can change the DependencyResolver to use your DI container of choice by setting GlobalHost.DependencyResolver.

NOTE: DO NOT override the global resolver in PreApplicationStart, it will not work, or it'll work only sometimes. Do it in PostApplicationStart (using WebActivator) or in Global.asax.

The important place here the NOTE. Of course after signalr 2.0 this documentation become deprecated. So I mixed some of here with the new SignalR API. In new SignalR API not using WebActivatorEx anymore. OwinStartup preferred instead of WebActivator.

[assembly: OwinStartupAttribute(typeof(YourNamespace.Startup))]
namespace YourNamespace
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            //IoC container registration process
            UnityConfig.RegisterComponents();

            UnityConfig.Container.RegisterType<AHub, AHub>();

            HubConfiguration config = new HubConfiguration();
            config.EnableJavaScriptProxies = true;


            //You should remove your dependency resolver code from here to Global.asax Application_Start method. Before setting the MVC properties.
            //config.Resolver = new SignalrDefaultDependencyResolver(UnityConfig.Container); // your dependency resolver
            //


            app.MapSignalR(config);
        }
    }
}

And in your global.asax

namespace YourNamespace
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            //Here your SignalR dependency resolver
            GlobalHost.DependencyResolver = new SignalrDefaultDependencyResolver(UnityConfig.Container);


            //other settings goes on
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);

            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
    }
}

I dont want to send all the code here, for showing up the real problem.

So for me everything works fine for now. Dependency injection also works too. But the bad part is everywhere that I searched David Fowler was saying "Its by design". I started to think is this design really a necessary or a mistake.

Hope it helps somebody else who makes research for same problem.

I had the same issue, and it is related to IoC (with whatever such as ninject or castle). If you set the global dependency resolver to your IoC manager, it will also replace the SignalR inner pipeline resolution. This makes your SingleTon client hub, not work correctly.

I solved it by only having the Server Hubs being IoC-ed The code below requires SignalHubActivator (you can find it on the internet)

Now, GlobalHost.ConnectionManager.GetHubContext will return the single instance AND client methods will be called correctly again!

 //configuration.Resolver = signalrDependency ; dont, this will cause GlobalHost.ConnectionManager to be intercepted by Castle


 configuration.Resolver.Register(typeof(IHubActivator),
                                      () => new SignalHubActivator(container));
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!