SignalR with IoC (Castle Windsor) - which lifetime for hubs?

邮差的信 提交于 2019-12-01 06:36:17

By default SignalR does not register each hub with the dependency resolver. Instead it uses an IAssemblyLocator to find available assemblies that might contain SignalR Hubs. Then the IHubDescriptorProvider searches through all the available assemblies for Hubs and creates HubDescriptors.

Lastly, the IHubActivator takes a HubDescriptor and returns a newly instantiated SignalR hub (using Activator.CreateInstance) unless the Hub type associated with the HubDescriptor has been registered with the dependency resolver. In the latter case, the Hub returned from the IHubActivator will be taken directly from the dependency resolver.

Typically SignalR hubs are ephemeral meaning that they get created and destroyed for each Hub method invocation. This means that if you register your Hub with SignalR's dependency resolver, you should make sure that a new Hub instance is returned each time SignalR resolves the Hub type.

I strongly advise against registering a singleton Hub for several reasons:

  1. Hub methods can be called in parallel. When this happens, Hub.Context can be overridden as part of the setup for another method call. This can lead to really subtle bugs. For example, with a singleton Hub, the following code might add a connection other than the caller to a group (which could obviously be a big security issue):

    [Authorize(Roles="Admin")]
    public async Task JoinAdminGroup()
    {
        await Groups.Add(Context.ConnectionId, "admin");
    }
    
  2. Hub.Dispose will be called after each activation. If you keep returning the same Hub, it's Dispose method will be repeatedly called. This probably won't affect you unless you implement Dispose on your Hubs, since the default Dispose implementation currently no-ops.

  3. IIS recycles AppDomains. When this happens, you will be forced to reinstantiate your Hub anyway. Remember, SignalR will automatically reestablish active connections after your app becomes unavailable for a short period of time (as is the case with an AppDomain recycle), so you can very well have a newly instantiated Hub dealing with pre-existing connections even if you register your Hub as a Singleton with the dependency resolver.

https://github.com/SignalR/SignalR/blob/2.0.1/src/Microsoft.AspNet.SignalR.Core/DefaultDependencyResolver.cs#L79

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