2

My app flow is as follows (simplified for clarity):

  1. User GETs a page from "/page1"
  2. User performs actions on the page (adds text, clicks, etc..), while Signalr communicates this data to the server, which performs heavy calculations in the background, and the results of those are returned to the page (lets call those "X").
  3. When the user is finished with the page, he clicks a link to "/page2", that is returned by Nancy. This page is built using a Model that is dependent on X.

So, how do I build that Model based on X? How can signalr write to the user session in a way that Nancy can pick up on?

(I'm looking for a "clean" way)

seldary
  • 6,186
  • 4
  • 40
  • 55
  • 1
    It's worth noting, JabbR is now run using SignalR and NancyFX together. You can checkout that repo https://github.com/davidfowl/JabbR – Phill Jan 31 '13 at 12:56

2 Answers2

8

Pending formal integration of Signalr & Nancy, this is what I came with. Basically, I share an IOC container between the two, and use an object (singleton lifetime) that maps users to state.

How to share an IOC container using the built in TinyIOC:

  1. Extend Signalr's DefaultDependencyResolver

    public class TinyIoCDependencyResolver : DefaultDependencyResolver
    {
        private readonly TinyIoCContainer m_Container;
    
        public TinyIoCDependencyResolver(TinyIoCContainer container)
        {
            m_Container = container;
        }
    
        public override object GetService(Type serviceType)
        {
            return m_Container.CanResolve(serviceType) ? m_Container.Resolve(serviceType) : base.GetService(serviceType);
        }
    
        public override IEnumerable<object> GetServices(Type serviceType)
        {
            var objects = m_Container.CanResolve(serviceType) ? m_Container.ResolveAll(serviceType) : new object[] { };
            return objects.Concat(base.GetServices(serviceType));
        }
    }
    
  2. Replace Signalr's default DependencyResolver with our new one

    public class Bootstrapper : DefaultNancyBootstrapper
    {
        protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
        {
            CookieBasedSessions.Enable(pipelines);
    
            // Replace UserToStateMap with your class of choice
            container.Register<IUserToStateMap, UserToStateMap>();
    
            GlobalHost.DependencyResolver = new TinyIoCDependencyResolver(container);
            RouteTable.Routes.MapHubs();
        }
    }
    
  3. Add IUserToStateMap as a dependency in your hubs and Nancy modules

    public class MyModule : NancyModule
    {
        public MyModule(IUserToStateMap userToStateMap)
        {
            Get["/"] = o =>
            {
                var userId = Session["userId"];
                var state = userToStateMap[userId];
                return state.Foo;
            };
        }
    }
    
    public class MyHub : Hub
    {
        private readonly IUserToStateMap m_UserToStateMap;
    
        public MyHub(IUserToStateMap userToStateMap)
        {
            m_UserToStateMap = userToStateMap;
        }
    
        public string MySignalrMethod(string userId)
        {
            var state = userToStateMap[userId];
            return state.Bar;
        }
    }
    

What I would really want, is a way to easily share state between the two based on the connection ID or something like that, but in the meantime this solution works for me.

seldary
  • 6,186
  • 4
  • 40
  • 55
2

Did you arrive hear looking for a simple example of how to integrate Nancy and SignalR? I know I did.

Try this question instead (I self-answered it).

Community
  • 1
  • 1
biofractal
  • 18,963
  • 12
  • 70
  • 116
  • This could use an update, it's an excellent set of examples, but newer versions of Signalr have some notable differences. – Chris Pfohl Feb 07 '15 at 15:48
  • I agree. So I have now updated the example code to use the latest assemblies as requested. I did the minimum work to convert it and get it working again so if you feel that there are now better techniques then I would be super-grateful if you made the changes and send a pull request. – biofractal Feb 07 '15 at 17:32