Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SignalR Requests Throwing "Hub could not be resolved."

I've been using SignalR since an early version and upgraded along the way however I have deployed my application to my Windows Server 2008 R2 production server and now the app crashes out with the " Hub could not be resolved." exception.

edit: StackTrace Added:

[InvalidOperationException: 'stockitems' Hub could not be resolved.]
Microsoft.AspNet.SignalR.Hubs.HubManagerExtensions.EnsureHub(IHubManager hubManager,  String hubName, IPerformanceCounter[] counters) +426
Microsoft.AspNet.SignalR.Hubs.HubDispatcher.Initialize(IDependencyResolver resolver, HostContext context) +716
Microsoft.AspNet.SignalR.Owin.CallHandler.Invoke(IDictionary`2 environment) +1075
Microsoft.AspNet.SignalR.Owin.Handlers.HubDispatcherHandler.Invoke(IDictionary`2 environment) +363
Microsoft.Owin.Host.SystemWeb.OwinCallContext.Execute() +68
Microsoft.Owin.Host.SystemWeb.OwinHttpHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object extraData) +414

[TargetInvocationException: Exception has been thrown by the target of an invocation.]
Microsoft.Owin.Host.SystemWeb.CallContextAsyncResult.End(IAsyncResult result) +146
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +606
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +288

On my dev machine and local test server I am getting no issues.

The hub in question is really simple:

 [HubName("StockItems")]
public class StockItemHub : Hub
{

}

Originally I thought it was an issue with the HubName so removed it but it still bombs out.

Originally I thought it was due to dependency injection so I then changed my Global.asax to look as follows:

    var signalRResolver = new SignalRDependencyResolver();
        GlobalHost.DependencyResolver = signalRResolver;

        var configuration = new HubConfiguration { Resolver = signalRResolver };
        RouteTable.Routes.MapHubs(configuration);

        AreaRegistration.RegisterAllAreas();

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

edit: what is SignalRDependencyResolver? SignalRDependencyResolver didn't exist until I tried to solve this issue. As I believe its a dependency injection issue I wrapped DefaultDependencyResolver overrode GetService and GetServices to first check my Ninject kernel for the type and if not fall back to the DefaultDependencyResolver

Any ideas?

The server is running IIS7, Windows Server 2008 with .Net 4.5 The application is an MVC 4 .Net 4.5

like image 647
MJJames Avatar asked Jan 24 '13 21:01

MJJames


2 Answers

I had this same error due to my Hub class being internal, therefore SignalR couldn't find it within my assembly.

Setting the hub to public solved the issue.

like image 54
Connell Avatar answered Sep 25 '22 14:09

Connell


I suffer from this problem just now, and I dig in a little deeper, and have just found out a possible solution. My hub class are not in assembly of the web project, they are in some referenced assemblies. This is a very common scenario in a multi-layer application.

When starting up, signalR will try to find hub class by an IAssemblyLocator instance. When deployed within an IIS site, this IAssemblyLocator instance find through all referenced assemblies. But at this point of time, the application is just during the startup, which means many (referenced but not loaded yet) assemblies may had NOT been gathered by owin host environment. So the lookup for hub classes fails.

So, just add your assembly into system.web/compilation/assemblies section of Web.Config:

<system.web>
  <compilation targetFramework="4.5">
    <assemblies>
      <add assembly="HubAssembly, Version=1.0.0.0, Culture=neutral"/>
    </assemblies>
  </compilation>
</system.web>

Or if you like, you can also solved this problem by implementing a custom IAssemblyLocator class, register it into the dependency resolver as soon as app.MapSignalR is invoked.

using Microsoft.AspNet.SignalR.Hubs;
public class AssemblyLocator : IAssemblyLocator {
     public IList<System.Reflection.Assembly> GetAssemblies()
     {
         // list your hubclass assemblies here
         return new List<System.Reflection.Assembly>(new []{typeof(HubAssembly.HubClass).Assembly});
     }
}


// add following code to OwinStartup class's Configuration method
app.MapSignalR();
GlobalHost.DependencyResolver.Register(typeof(Microsoft.AspNet.SignalR.Hubs.IAssemblyLocator), () => new AssemblyLocator());
like image 25
Jijie Chen Avatar answered Sep 21 '22 14:09

Jijie Chen