Update UI with SignalR and Knockout when manually updating DB

后端 未结 2 701
遇见更好的自我
遇见更好的自我 2021-01-24 22:38

I have had a search around SO for this, but didn\'t come across anything obvious. I have a dashboard of jobs, and their status continually changes throughout the day and I\'m t

2条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-01-24 23:08

    Update I've extracted my code and put it on Github/nuget https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy

    To install to a MVC proejct

    Install-Package SignalR.EventAggregatorProxy
    

    Old answer

    I just did this for one of my customers project, I used this EventAggregator that I created for a open source project called FreePIE

    https://github.com/AndersMalmgren/FreePIE/tree/master/FreePIE.Core/Common/Events

    Quick read up on EventAggregators http://codebetter.com/jeremymiller/2009/07/22/braindump-on-the-event-aggregator-pattern/

    The repository code looks look like this

    public class FooRepository : Repository 
    {
       private readonly IEventAggregator eventAggregator;
    
       public FooRepository(IEventAggregator eventAggregator) {
          this.eventAggregator = eventAggregator;
       }
    
       public void SaveFoo(Foo foo)
       {
          //save foo
          this.eventAggregator.Publish(new FooSavedEvent(foo));
       }
    }
    

    In the event aggregator hub (SignalR) i do

    public class ClientEventAggregator : Hub
    {
       public ClientEventAggregator (IEventAggregatorClientProxy proxy)
       {
          //This is just a way of injecting the singleton proxy for the first hub connection
       }
    }
    

    Proxy that handles all backend events fired by the EventAggregator.
    IHandle can be changed to for example a base class IHandle this way you can choose which backend events to forward to client

    public class EventAggregatorClientProxy : IEventAggregatorClientProxy, IHandle
    {
       public EventAggregatorClientProxy(IEventAggregator eventAggregator) 
       {
          eventAggregator.Subscribe(this);
       }
    
       public void Handle(object event)
       {
          var context = GlobalHost.ConnectionManager.GetHubContext();
          context.Clients.All.event(new { Type = event.GetType().Name, Event = event });
       }
    }
    
    
    

    In my example all events will be sent to all clients you could implement rules for that and change context.Clients.All

    On the client I re publish the event using this little event aggreagator that i wrote for another SO question http://jsfiddle.net/wJtun/4/

    MyApp.MasterViewModel = function() {
        var event = $.connection.clientEventAggregator;
    
        event.client.event = this.onEvent.bind(this);
    
        $.connection.hub.start().done();
        });
    };
    MyApp.MasterViewModel.prototype = {
       onEvent: function(event) {
          var type = MyApp.Events[event.type];          
          MyApp.eventAggregator.publish(new type(event.event));
       }
    };
    

    var type = MyApp.Events[event.type]

    Note that this requires that you have defined a javascript class MyApp.Events.FooSavedEvent. Or that you dynamically create a JS that contains all Events that can be published (You can look at the SignalR code how they create the Hub proxy).

    Disclaimer: All code above was written directly in the SO editor out of memory, it can contain errors

    提交回复
    热议问题