nov 28, 2013

Orchard + SignalR + Knockout.Js e applicazioni Real-time

Translations:

In questo articolo vedremo come è possibile creare funzionalità Real-time in Orchard CMS utilizzando SignalR e Knockout.Js.

Le chiamate asincrone tra l'html e il server verranno gestite da SignalR mentre Knockout.js servirà a generare dinamicamente tag html in base ai dati JSON restituiti.

I punti di forza di un approccio di questo genere sono:

- Operazioni asincrone che non bloccano l'utente tra request e response in una classica post dell'intera pagina.
- Trasferimento delle sole informazioni in formato JSON.
- Possibilità di notifiche PUSH a tutti gli utenti connessi o a gruppi di essi.

Quello che ci accingiamo a realizzare è un semplice pulsante che una volta premuto ci restituirà una lista di contenuti letti dal database.

Iniziamo creando un nuovo modulo:

codegen module testSignalR /includeinsolution:true

Installiamo il modulo Proligence SignalR che contiene i riferimenti a SignalR.

Scarichiamo Knockout.Js e copiamo il file js nella cartella script del nostro modulo.

All'interno del nostro modulo aggiungiamo una nuova cartella chiamata Hubs e creiamo una classe TestHub come la seguente: 

  public class TestHub : Hub {
        private readonly IOrchardServices _services;

        public TestHub(IOrchardServices services) {
            _services = services;
        }

        public void Test() {

            IEnumerable<dynamic> list = _services.ContentManager.Query().ForType("Articolo").List();

            var lista2 = list.Select(item => new {Id = item.Id, Title = item.TitlePart.Title});

            Clients.Caller.testNotify(lista2);
        }
    } 

Ho creato un metodo Test() di esempio che ritorna una serie di dati di prova. Dopo aver interrogato il database, questo metodo, crea una lista di Id e Titolo. A questo punto la lista viene passata tramite SignalR alla funzione client-side testNotify:

Clients.Caller.testNotify(lista2);

Aggiungiamo la view:

@{ 
    Script.Require("jQuery_SignalR_Hubs").AtHead();
    
    Script.Include("knockout-3.0.0.js").AtHead();
}

@using (Script.Head())
{
    <script>
        $(function () {
            "use strict";

            function contentsViweModel() {

                var self = this;

                self.hub = $.connection.testHub;
                
                self.contents = ko.observableArray();
                
                self.test = function() {
                    self.hub.server.test();
                };
                
                self.hub.client.testNotify = function (contents) {
                    self.contents(contents);
                };
                
                self.clear = function () {
                    self.contents(null);
                };
            };

            var vm = new contentsViweModel();
            ko.applyBindings(vm);
            
            $.connection.hub.start();
        });
    </script>
}
    <div class="page-header">
        <h1>Real time test</h1>
        <h3>Using Knockout.Js and SignalR</h3>
    </div>

<button id="btnTest"  data-bind='click: $root.test'>@T("Test")</button>
<button id="btnTestClear"  data-bind='click: $root.clear'>@T("Clear")</button>

<fieldset class="contentItems bulk-items">
    <ul data-bind ="foreach: contents">
        <li>
            <div class="summary">
                <div class="properties">
                    <h3 data-bind="text: Title"></h3>
                </div>
            </div>
        </li>
    </ul>
</fieldset>

La funzione testNotify(contents) viene richiamata direttamente dal server e setta una variabile contents con gli oggetti JSON letti dal database. Questa variabile è stata definita observableArray e quindi Knockout si prenderà carico di aggiornare l'html che è stato bindato ad esso nel momento stesso che il contenuto della variabile viene modificato.

Tags: Orchard, C#, SignalR, Knockout.Js


© 2017 Bunny's Attack