我从早期版本开始就使用SignalR并一路升级但是我已经将我的应用程序部署到我的Windows Server 2008 R2生产服务器上,现在应用程序因“无法解决集线器”而崩溃。异常。
编辑:StackTrace已添加:
[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
在我的开发机器和本地测试服务器上,我没有遇到任何问题。
有问题的中心非常简单:
[HubName("StockItems")]
public class StockItemHub : Hub
{
}
最初我认为这是HubName的一个问题,所以删除它但它仍然炸弹。
最初我认为这是因为依赖注入,所以我将Global.asax更改为如下所示:
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);
编辑:什么是SignalRDependencyResolver? 在我尝试解决此问题之前,SignalRDependencyResolver不存在。由于我认为它是一个依赖注入问题,我将DefaultDependencyResolver包装为覆盖GetService和GetServices,首先检查我的Ninject内核的类型,如果没有回退到DefaultDependencyResolver
有什么想法吗?
服务器正在运行带有.Net 4.5的IIS7,Windows Server 2008 该应用程序是MVC 4 .Net 4.5
答案 0 :(得分:11)
由于我的Hub
类为internal
,我遇到了同样的错误,因此SignalR无法在我的程序集中找到它。
将中心设置为public
解决了问题。
答案 1 :(得分:6)
我刚刚遇到这个问题,我深入挖掘,并找到了可能的解决方案。 我的集线器类不在Web项目的汇编中,它们在一些引用的程序集中。这是多层应用程序中非常常见的情况。
启动时,signalR将尝试通过IAssemblyLocator实例查找集线器类。在IIS站点中部署时,此IAssemblyLocator实例将查找所有引用的程序集。但是在这个时间点,应用程序只是在启动期间,这意味着许多(已引用但尚未加载)的程序集可能尚未被owin主机环境收集。 因此,集线器类的查找失败。
因此,只需将程序集添加到Web.Config的system.web / compilation / assemblies部分:
<system.web>
<compilation targetFramework="4.5">
<assemblies>
<add assembly="HubAssembly, Version=1.0.0.0, Culture=neutral"/>
</assemblies>
</compilation>
</system.web>
或者,如果您愿意,也可以通过实现自定义IAssemblyLocator类来解决此问题,只要调用app.MapSignalR就将其注册到依赖项解析器中。
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());
答案 2 :(得分:3)
现在这是一个古老的问题,但本周末又重新抬起头来。在花了很多时间进行调查之后,我发现SignalR并不是部署中唯一被破坏的东西,我的WebAPI也投掷无法找到控制器异常。
事实证明,这是由于SignalR和WebApi的内部结构反映了Sites部署中的所有类型。在我的情况下抛出了TypeLoadException,因为有一个类派生了RoleEntryPoint,这是一个Azure类型,但是由于该站点部署在非Azure环境中,所以事情就崩溃了。简单地从非Azure版本中排除此类型解决了该问题。
如果这些TypeLoadExceptions更加明显,那就更好了。
答案 3 :(得分:1)
与@Jijie Chen类似,当我遇到这个问题时,我发现它无法加载包含我的集线器的程序集。对我来说,修复更简单。就我而言,我有三个项目。所有逻辑,包括集线器都在自己的项目中,我有两个项目打算使用owin。一个是一个工作正常的控制台项目。然后我将其改编为Windows服务来托管它。好吧,不知何故,我设法忘记包含对包含我的集线器的项目的引用。这仍然编译正常,因为主机代码依赖于signalr / owin映射函数,这些函数在运行时加载集线器而不是编译时。因此,当我启动服务并尝试连接时,我得到了集线器没有在此描述的定义错误,因为它无法找到我的集线器的程序集。