Phil Phil - 5 months ago 41
jQuery Question

using signalR to update multiple views with 1 broadcast

I'm using MVC 5 with signalR 2. I have a page that has a main layout template that uses signalR to update some part of that template. I also have a partial view on that page that needs to refresh from that same signalR broadcast that the layout template is using. Basically in the template i have:

var entrypush;
$(document).ready(function () {
entrypush = $.connection.entryHub;
entrypush.client.entryUpdated = refreshLayout;
$.connection.hub.start();
});


but the partial view will need to respond to this same 'entryUpdated' broadcast call from signalR. What is the best way to handle this? Should i just create an entirely new hub on the partial view, so that i have?

var entrypushPV;
$(document).ready(function () {
entrypushPV = $.connection.entryHub;
entrypushPV.client.entryUpdated = refreshPartialView;
$.connection.hub.start();
});


This seems like a bad idea but i can't think of a way around this. Would it be better to duplicate methods on the hub instead? So that instead of just pushing 'entryUpdated', I then push 'entryUpdateForLayout' and 'entryUpdateForPartialView'? That way i could avoid creating duplicate hubs, but I'm duplicating push calls in this way instead.

Answer

I would like to preface this by saying that I am by no means a JavaScript wizard, so take this with a grain of salt, and modify it as necessary. In this code, I open a connection to my SignalR hub in a javascript file, and then create an event which is raised when a client side function is invoked. Then you can listen to this event where needed:

hubconnection.js

$(document).ready(function () {
    var entrypush;
    entrypush = $.connection.entryHub;

    //setup event
    var event = document.createEvent('Event');
    event.initEvent('refresh', true, true);

    //define the function that is called when entrypush.client.entryUpdated is called. obj is data passed from the hub
    refresh = function (obj) {
        event.data = obj;
        document.dispatchEvent(event);
    };

    entrypush.client.entryUpdated = refresh;

    //connect to hub
    $.connection.hub.start();
});

_Layout.cshtml

<head>
    //jquery + SignalR stuff...

    <script src="~/Scripts/hubconnection.js"></script>

    <script>
    document.addEventListener('refresh', function (e) {
        //do stuff with e.data here, if necessary.
    }, false);
    </script>
</head>

_Partial

<script>
        document.addEventListener('refresh', function (e) {
            //do stuff with e.data here, if necessary.
        }, false);
</script>

If this is unclear, or it seems like something is missing, let me know.