Last post Jul 27, 2016 03:35 PM by superjose
Jul 13, 2016 01:48 PM|superjose|LINK
Hi people! I've been struggling for this for a while. I have a not so small SignalR logic (Paired with ASP.NET MVC 5 and Identity 2.0) which I ended up dividing in Client, Logic and Hub classes. The Hub receives injection of the Logic, and the Logic receives
injection of the Client. Unfortunately after I started applying this mechanism, SignalR takes ages to send some data from client to server, and server to other client. Funny thing is, that I know the main reason behind it: Ninject is recreating all those classes
and disposing them as soon as a signal is sent or received.
I went ahead and triggered the "InSingletonScope" from Ninject, and saw a brutal 4,000% increase in speed. But this ended up creating me a super disaster. The Context from Entity Framework started to get disposed before being actually needed and whenever
I tried to lazy/eager load data from the database it would come back incomplete/unloaded.
I tried migrating my application to AutoFac but I had some problems on getting the GlobalhostContext to work as I have with Ninject.
Here is my code:
This is the NinjectDependencyResolver:
public class NinjectDependencyResolver : IDependencyResolver
private IKernel kernel;
public NinjectDependencyResolver(IKernel kernelParam)
kernel = kernelParam;
public object GetService(Type serviceType)
public IKernel GetKernel()
public IEnumerable<object> GetServices(Type serviceType)
private void AddBindings()
var matchContext = GlobalHost.ConnectionManager.GetHubContext("MatchHub");
var tourneyContext = GlobalHost.ConnectionManager.GetHubContext("TournamentHub");
var organizerContext = GlobalHost.ConnectionManager.GetHubContext("OrganizerHub");
var chatContext = GlobalHost.ConnectionManager.GetHubContext("ChatHub");
* Do not remove Signleton. Although it may look fishy, SignalR is a persistent connection. It will stay
* alive throughout the entire application. All these contexts will not change and do not need to be closed.
* In fact, having the Singleton Scope has yielded me around 4,000% increase. Without it, the application was so
* painfully slow. Now, it's brutally fast!!!
This is the constructor of my MatchHub:
public class MatchHub : BaseHub
private readonly IMatchHubLogic _matchHubLogic;
private readonly IHelperUtility _helperUtility;
private readonly ITournamentHubLogic _tournamentLogic;
private readonly IUserId _userId;
public MatchHub(IUserId userId, ITournamentHubLogic tournamentLogic,
IHelperUtility helperUtility, IMatchLogic matchLogic, IHubDataAccess dataAccess, IParticipantLogic participantLogic
, ITournamentHubClient tourneyHubClient, IGrantAccess grantAccess, IHubLogic hubLogic)
_userId = userId;
var matchCon = GlobalHost.ConnectionManager.GetHubContext("MatchHub");
* I know this is kind of awful, but this is the best way to do this:
* If I leave Ninject to manipulate the context for me, it would be so freaking slow.
* Already tried with (default), InRequestScope(), InTranscientScope.
* But then, the fastest one is SingletonScope(). That's lightning! :D Unfortunately,
* there is a huge problem with the context. It creates a mind-bogging problem with everything.
* Because since it is Singleton it will not receive the new DbContext and it will fail. Even by forcing
* the DbContext to InRequestScope or InThreadScope. So the only feasible way to do this is via
* Poorman's DI.
* It's not as fast as Singleton, but none of the problems show up.
_matchHubLogic = new MatchHubLogic(matchLogic, matchCon, dataAccess, participantLogic, tourneyHubClient, grantAccess, hubLogic);
_tournamentLogic = tournamentLogic;
_helperUtility = helperUtility;
//All hubs methods omitted due to brevity.
public class MatchHubLogic : IMatchHubLogic
public MatchHubLogic(IMatchLogic matchLogic, IHubContext matchHubContext, IHubDataAccess dataAccess,
IParticipantLogic participantLogic, ITournamentHubClient tourneyHubClient,
IGrantAccess grantAccess, IHubLogic hubLogic)
_matchLogic = matchLogic;
_matchHubContext = matchHubContext;
_dataAccess = dataAccess;
_tourneyHubClient = tourneyHubClient;
_matchHubClient = new MatchHubClient(matchHubContext);
_participantLogic = participantLogic;
_grantAccess = grantAccess;
_hubLogic = hubLogic;
I ended up doing Poorman's DI for speed concerns and to prevent the Context to get disposed behind time....
Jul 15, 2016 08:52 AM|Fei Han - MSFT|LINK
SignalR takes ages to send some data from client to server
I’d like to know the size of data you are passing between client and hub server.
Jul 22, 2016 12:43 AM|superjose|LINK
Hi Fei Han. Super duper simple numbers. Literally... Form zero to two. Or simple messages. Everything is plain text.
Jul 27, 2016 03:35 PM|superjose|LINK
Simple messages go fast.
The problem is when I try to do some server calculations, (some of them involve doing external API calls to a REST service). But I don't think that the code is running slow, because whenever I used to have the Hub in only one script, everything was running
And, as I was pointing out in my first post, AutoFac is somewhat painful to use when I need to inject into SignalR. That happens because I need the GlobalHostContext to be injected in runtime, which Ninject does it painlessly.