Frage Echtzeitdaten in einem Raster - bessere Methode


Was ist für Sie der bessere Ansatz, um Echtzeitdaten (Börse, Wetter, ...) in einem Raster anzuzeigen?
Ich benutze diese Methode:

setInterval(function(){
      jQuery("#list1").trigger('reloadGrid');
}, 5000);

17
2018-05-05 11:08


Ursprung


Antworten:


Ich finde deine Frage sehr interessant. Ich denke, die Frage könnte für viele andere Nutzer interessant sein. Also +1 von mir.

Die Verwendung von setInterval Näht sich mir am besten im üblichen Browser-unabhängigen Fall. Man sollte das Ergebnis speichern setInterval in einer Variablen verwenden können clearInterval um es zu stoppen.

Eine weitere kleine Verbesserung wäre die Verwendung von [{current:true}] (sehen die Antwort für Details) als der zweite Parameter von trigger:

var $grid = jQuery("#list1"), timer;

timer = setInterval(function () {
    $grid.trigger('reloadGrid', [{current: true}]);
}, 5000);

Es speichert die Auswahl beim Neuladen des Gitters.

Viele neue Webbrowser unterstützen jetzt WebSocket. Es wäre also besser, den Weg zu wählen, falls der Webbrowser dies unterstützt. Auf die Art, wie man nicht benötigtes Grid-Reload überspringen kann, falls die Daten auf dem Server nicht verändert werden und ein permanentes Pooling des Servers verhindert wird.

Ein weiterer häufiger Weg scheint mir auch sehr interessant. Wenn man eine Art Zeitstempel der letzten Änderungen der Gitterdaten verwenden würde, könnte man überprüfen, ob die Daten geändert wurden oder nicht. Man kann beides nutzen ETag oder eine allgemeine zusätzliche Methode auf dem Server für diesen Zweck.

Die jetzige Erfolg Rückruf von jQuery.ajax Welche füllen jqGrid können Sie verwenden, um zu implementieren beforeProcessing Rückruf zu ändern die Antwort des Servers, aber es ist Sie können jqGrid nicht auffrischen beyogen auf jqXHR.satus Wert (es wäre xhr.status im aktuellen jqGrid-Code). Kleine Modifikation von die Linie Mit dem Code von jqGrid können Sie die Aktualisierung von jqGrid bei unveränderten Daten auf dem Server stoppen. Man kann entweder testen textStatus (st im aktuellen Code von jqGrid) für "notmodified" oder testen jqXHR.satus (xhr.status im aktuellen jqGrid-Code) für 304. Es ist wichtig, dass Sie das Szenario verwenden, das Sie verwenden sollten prmNames: { nd:null } Option und einstellen ETag und Cache-Control: private, max-age=0 (sehen Hier, Hier und Hier für weitere Informationen).

AKTUALISIERT: Ich habe versucht, das Demo-Projekt basierend auf meinen letzten Vorschlägen zu erstellen und habe festgestellt, dass es nicht so einfach ist, wie ich oben beschrieben habe. Trotzdem habe ich es zum Laufen gebracht. Die Schwierigkeit bestand darin, dass der 304-Code von der Serverantwort in jQuery.ajax nicht angezeigt werden konnte. Der Grund war der folgende Ort in der XMLHttpRequest-Spezifikation

Zum 304 Nicht geändert Antworten, die ein Ergebnis eines Benutzeragenten sind   generierte bedingte Anfrage der User-Agent muss sich wie der Server verhalten   gab ein 200 OK Antwort mit dem entsprechenden Inhalt. Der Benutzeragent   muss zulassen, dass Autoranforderungsheader den automatischen Cache überschreiben   Validierung (z.B. If-None-Match oder If-Modified-Since), in welchem ​​Fall    304 Nicht geändert Antworten müssen weitergegeben werden.

So sieht man 200 OK Status innerhalb von successHandler von $.ajax stattdessen 304 Nicht geändert von der Serverantwort. Es scheint, dass XMLHttpRequest bekomme nur volle Antwort vom Cache inklusive aller HTTP-Header zurück. Also entscheide ich mich, die Analyse von zwischengespeicherten Daten zu ändern, nur um zu speichern ETag von der letzten HTTP-Antwort als neuer jqGrid-Parameter und Testen der ETag der neuen Antwort mit den gespeicherten Daten.

Ich habe gesehen, dass Sie PHP benutzen (was ich nicht verwende :-(). Trotzdem kann ich PHP-Code lesen und verstehen. Ich hoffe, Sie können auf die gleiche Weise C # -Code lesen und verstehen die Hauptidee. So werden Sie in der Lage sein Implementiere das Gleiche in PHP.

Jetzt beschreibe ich, was ich getan habe. Zuerst habe ich modifiziert Die Linien von jqGrid Quellcode die verwenden beforeProcessing Rückruf von

if ($.isFunction(ts.p.beforeProcessing)) {
    ts.p.beforeProcessing.call(ts, data, st, xhr);
}

zu

if ($.isFunction(ts.p.beforeProcessing)) {
    if (ts.p.beforeProcessing.call(ts, data, st, xhr) === false) {
        endReq();
        return;
    }
}

Es wird erlaubt, von falsch zurückzugeben beforeProcessing Überspringen der Aktualisierung von Daten - um die Verarbeitung von Daten zu überspringen. Die Implementierung von beforeProcessing Was ich in der Demo verwendet habe, basiert auf der Verwendung ETag:

beforeProcessing: function (data, status, jqXHR) {
    var currentETag = jqXHR.getResponseHeader("ETag"), $this = $(this),
        eTagOfGridData = $this.jqGrid('getGridParam', "eTagOfGridData");
    if (currentETag === eTagOfGridData) {
        $("#isProcessed").text("Processing skipped!!!");
        return false;
    }
    $this.jqGrid('setGridParam', { eTagOfGridData: currentETag });
    $("#isProcessed").text("Processed");
}

Die Linie $("#isProcessed").text("Processed"); oder die Linie $("#isProcessed").text("Processing skipped!!!"); einstellen "Processed" oder "Processing skipped!!!" Text in der Div, die ich verwendet habe, um visuell anzuzeigen, dass die Daten vom Server verwendet wurden, um das Raster zu füllen.

In der Demo Ich zeige zwei Gitter mit den gleichen Daten an. Das erste Raster, das ich für die Bearbeitung von Daten verwende. Das zweite Raster ruft die Daten jede Sekunde vom Server ab. Wenn die Daten auf dem Server nicht geändert werden, sieht der HTTP-Verkehr wie folgt aus

HTTP-Anfrage:

GET http://localhost:34336/Home/DynamicGridData?search=false&rows=10&page=1&sidx=Id&sord=desc&filters= HTTP/1.1
X-Requested-With: XMLHttpRequest
Accept: application/json, text/javascript, */*; q=0.01
Referer: http://localhost:34336/
Accept-Language: de-DE
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; LEN2)
Host: localhost:34336
If-None-Match: D5k+rkf3T7SDQl8b4/Y1aQ==
Connection: Keep-Alive

HTTP-Antwort:

HTTP/1.1 304 Not Modified
Server: ASP.NET Development Server/10.0.0.0
Date: Sun, 06 May 2012 19:44:36 GMT
X-AspNet-Version: 4.0.30319
X-AspNetMvc-Version: 2.0
Cache-Control: private, max-age=0
ETag: D5k+rkf3T7SDQl8b4/Y1aQ==
Connection: Close

Damit Es werden keine Daten vom Server übertragen wenn die Daten nicht geändert werden. Wenn die Daten geändert werden, wird der HTTP-Header mit gestartet HTTP/1.1 200 OK und enthält ETag von neuen modifizierten Daten zusammen mit der Seite der Daten selbst.

Man kann die Daten des Gitters entweder manuell aktualisieren, indem man die Schaltfläche "Refresh" des Navigators verwendet oder die Schaltfläche "Start Autorefresh" verwendet, die ausgeführt wird $grid1.trigger('reloadGrid', [{ current: true}]); jede Sekunde. Die Seite sieht so aus

enter image description here

Ich habe die wichtigsten Teile am unteren Rand der Seite mit den Farbfeldern markiert. Wenn man loadui: "disable" Option dann sieht man während des Ziehens des Servers überhaupt keine Änderungen im Grid. Wenn man die Option kommentiert, wird man "Loading ..." div für sehr kurze Zeit sehen, aber kein Gitter enthalten wird flackern.

Nach dem Start von "Autorefreshing" sieht man meist das Bild wie unten

enter image description here

Wenn man eine Reihe im ersten Gitter ändert, wird das zweite Gitter in einer Sekunde geändert und man sieht es "Processed" Text, der geändert werden soll "Processing skipped!!!" Text in einer weiteren Sekunde.

Der entsprechende Code (ich habe ASP.NET MVC verwendet) auf der Serverseite ist meistens folgender

public JsonResult DynamicGridData(string sidx, string sord, int page, int rows,
                                  bool search, string filters)
{
    Response.Cache.SetCacheability (HttpCacheability.ServerAndPrivate);
    Response.Cache.SetMaxAge (new TimeSpan (0));

    var serializer = new JavaScriptSerializer();
    ... - do all the work and fill object var result with the data

    // calculate MD5 from the returned data and use it as ETag
    var str = serializer.Serialize (result);
    byte[] inputBytes = Encoding.ASCII.GetBytes(str);
    byte[] hash = MD5.Create().ComputeHash(inputBytes);
    string newETag = Convert.ToBase64String (hash);
    Response.Cache.SetETag (newETag);
    // compare ETag of the data which already has the client with ETag of response
    string incomingEtag = Request.Headers["If-None-Match"];
    if (String.Compare (incomingEtag, newETag, StringComparison.Ordinal) == 0) {
        // we don't need return the data which the client already have
        Response.SuppressContent = true;
        Response.StatusCode = (int)HttpStatusCode.NotModified;
        return null;
    }

    return Json (result, JsonRequestBehavior.AllowGet);
}

Ich hoffe, dass die Grundidee des Codes auch für Leute klar wird, die nicht nur ASP.NET MVC verwenden.

Sie können das Projekt herunterladen Hier.

AKTUALISIERT: Ich habe gepostet die Funktionsanfrage erlauben beforeProcessing um die Verarbeitung der Serverantwort durch Zurückgeben zu unterbrechen false Wert. Die entsprechenden Änderungen sind bereits enthalten (siehe Hier) im Haupt-jqGrid-Code. Die nächste Version von jqGrid wird es also beinhalten.


15
2018-05-05 12:45