Automatisches Aktualisieren einer .gsp-Datei in Grails, wenn sich eine Datenbanktabelle ändert

  • Was ich habe: - Eine Datenbanktabelle mit dem Namen 'orders', die ständig von einem Java-Modul im Backend aufgefüllt wird. - Eine auf Grails laufende Website, die diese anzeigt Aufträge. Genauer gesagt - eine list.gsp in der Ansicht Bestellungen. - list.gsp zeigt neue Bestellungen an, wenn im Browser auf die Aktualisierungsschaltfläche geklickt wird.

    Was ich brauche : - Eine Möglichkeit, die .gsp-Seite eines Clients automatisch zu aktualisieren, wenn eine neue Bestellung in der Datenbank platziert wird. - Die Autorefresh-Funktion muss die .gsp-Seite nur dann automatisch aktualisieren, wenn sich der Client bereits in der befindet .gsp Seite. Wenn sich also ein Client für eine bestimmte Reihenfolge in der show.gsp befindet, ist keine Autorefresh-Funktion erforderlich.

    Was ich zwar helfen könnte:

    • Option1: Mit einem Grails-Service, der in regelmäßigen Abständen (alle 5 Sekunden) die Datenbank abfragt, ob neue Bestellungen vorhanden sind. Wenn ja, dann irgendwie von der .gsp-Seite erneut aufrufen und die .gsp-Seite erneut rendern ??!

         - suboption1-1: create and destroy a new connection every 5 sec.
        - suboption1-2: create and keep a connection alive ... forever
       
    • Option2: Lassen Sie das Java-Modul, das die Bestellungen platziert, einen RefreshController über das Web aufrufen und die .gsp-Seite irgendwie erneut rendern. dh Lassen Sie den refreshController alle derzeit in der .gsp-Seite vorhandenen Clients darüber informieren, dass eine Aktualisierung erforderlich ist.

    ============ ================================================== ==================== Follow-up:

    Wie kann ich einen Controller aus Java-Skript aufrufen ?:

     function checkDB()
    {
       t = setTimeout("com.mypackage.DBChecker.checkdbController.checkAction()", 5000)
    }
     

    ====================== ================================================== =========== Follow-up 2:

    Also fast bekam ich, was ich wollte arbeiten, außer dass ich nicht herausfinden kann, wie man AJAX zurück zu meiner list.gsp-Seite nur einen Teil von sich. Ich möchte nicht die gesamte Seite aktualisieren, sondern nur eine Division mit id = "refresh table". d.h.

    Ich habe im Moment den folgenden Code, der nicht funktioniert:

        <script type="text/javascript">
            function checkDB()
            {
                var xmlhttp;
                var xmlDoc;
                var x;
                if (window.XMLHttpRequest)
                {// code for IE7+, Firefox, Chrome, Opera, Safari
                  xmlhttp=new XMLHttpRequest();
                }
                else
                {// code for IE6, IE5
                  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
                }
    
                xmlhttp.onreadystatechange=function()
                  {
                  if (xmlhttp.readyState==4 && xmlhttp.status==200)
                  {
                      xmlDoc=xmlhttp.responseText;
                      x=xmlDoc.getElementsByTagId("refreshTable");
                      for (i=0;i<x.length;i++)
                      {
                      txt = x[i].childNodes[0].nodeValue;
                      }               
                      document.getElementById("refreshTable").innerHTML=txt;
                  }
                  else
                          {
                          }
                  }
    
                xmlhttp.open("GET","http://localhost:8080/Orderlord/checkdb/checkdb",true);
                xmlhttp.send();
            }
            window.load = checkDB();
        </script>
     

    ============================================= =====================

    Folgen Sie 3:

    Es gelingt mir

    26 November 2011
    Martin Klosi
3 answers
  • Was Sie hier erklären, ist ein typisches Modell zum Publizieren und Abonnieren.

    Es gibt einige Plugins in Grails, die Ihnen dabei helfen werden. Schauen Sie sich dazu Atmosphere und CometD an. Beide Optionen bieten diese Art von Pub / Sub.

    Wenn sie sich etwas zu schwer fühlen, sollten Sie Pusher und das zugehörige Grails-Plugin. Es ist etwas schöner, da Sie einfach eine Javascript-Bibliothek in Ihre gsp-Seite integrieren können und den Push von der Serverseite aus durchführen können, wenn eine Bestellung erstellt wird. Fühlt sich etwas leichter als die beiden obigen Bibliotheken. Es verwendet HTML5-Web-Sockets.

    22 November 2011
    Tomas Lin
  • Sie können den Ansatz verfolgen, einen Timer auf der Seite über Javascript einzustellen . Sie rufen dann einen leichtgewichtigen Ajax-Aufruf von Ihrer gsp-Seite zurück an Ihren Controller, der ein wahr / falsch ergibt, um anzuzeigen, ob Sie eine vollständige Aktualisierung benötigen. Dies ist ein ziemlich einfacher Ansatz, aber Sie sollten darauf achten, dass das Back-End-Ziel des Ajax-Aufrufs optimiert wird, da es alle 5 Sekunden für jeden Benutzer auf dieser Seite aufgerufen wird. Es erzeugt auch einiges an Datenverkehr.

    Ich könnte die Plugins zum Veröffentlichen von Abonnements in der vorherigen Antwort untersuchen, bevor ich auf diesen Ansatz zurückgreife, jedoch habe ich den einfachen Timer / Ajax-Aufruf implementiert (in der Java Struts-Welt) auf einer mittelgroßen Website mit ziemlich guten Ergebnissen.

    22 November 2011
    Bill Pfeiffer
  • Der folgende Code in meiner list.gsp hat es also für mich getan. Ich entschied, dass das Aktualisieren des 'div id = "myDiv"' unter Frage alle 5 Sekunden gut ist, sonst hätte ich den Server sowieso alle 5 Sekunden angestoßen, seit ich die Datenbank abfrage.

         <script type="text/javascript">
            function ajaxrefresh()
            {
                var xmlhttp;
    
                if (window.XMLHttpRequest)
                {// code for IE7+, Firefox, Chrome, Opera, Safari
                  xmlhttp=new XMLHttpRequest();
                }
                else
                {// code for IE6, IE5
                  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
                }
    
                xmlhttp.onreadystatechange=function()
                  {
                  if (xmlhttp.readyState==4 && xmlhttp.status==200)
                    {
                    //alert("aaaaaaa")            
                    document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
                    }
                  else
                      {
                      //alert("state: "+xmlhttp.readyState)
                      //alert("status: "+xmlhttp.status)
                      }
                  }
    
                xmlhttp.open("GET","http://${localHostAddress}:12080/Orderlord/refresh/refreshactiveorders",true);
                xmlhttp.send();
    
                var t=setTimeout(ajaxrefresh,5000);
            }
    
            window.load = ajaxrefresh();
        </script>
     
    27 November 2011
    Martin Klosi