网格中的实时数据-更好的方法 [英] Real-time data in a grid - better method

查看:62
本文介绍了网格中的实时数据-更好的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在网格中显示实时数据(证券交易所,天气等)的更好方法是什么?
我使用这种方法:

What is for you the better approach for displaying real-time data (Stock Exchange, Weather, ...) in a grid ?
I use this method:

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

推荐答案

我发现您的问题非常有趣.我认为这个问题对于其他许多用户可能会很有趣.所以我+1.

I find your question very interesting. I think the question could be interesting for many other users. So +1 from me.

setInterval的使用为我提供了在与浏览器无关的常见情况下的最佳方法.一个原因应该将setInterval的结果保存在变量中,以便能够使用clearInterval停止它.

The usage of setInterval seams me the best way in common browser independent case. One should of cause save the result of setInterval in a variable to be able to use clearInterval to stop it.

另一个小改进是将[{current:true}]用作第二个参数(有关详细信息,请参见答案)的trigger:

One more small improvement would be the usage of [{current:true}] (see the answer for details) as the second parameter of trigger:

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

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

它将在重新加载网格时保存选择.

It will save selection during the reloading of grid.

许多新的Web浏览器现在支持 WebSocket .因此,最好在网络浏览器支持的情况下使用该方式.这样一来,如果服务器上的数据没有更改,就可以跳过不必要的网格重新加载,并防止服务器的永久池化.

Many new web browsers support now WebSocket. So it would be better to use the way in case if the web browser supports it. In the way one can skip unneeded grid reloading in case if the data are not changed on server and prevent permanent pooling of the server.

在我看来,一种更常见的方式也很有趣.如果要使用网格数据最后一次更改的某种时间戳,则可以验证数据是否已更改.为此,可以在服务器上使用 ETag 或其他一些常规方法.

One more common way seems to me also very interesting. If one would use some kind of timestamp of the last changes of the grid data one could verify whether the data are changed or not. One can either uses ETag or some general additional method on the server for the purpose.

当前成功 jQuery.ajax 的a>回调,其中填充jqGrid允许您用于实现beforeProcessing回调修改服务器响应,但不允许您基于jqXHR.satus值(在当前jqGrid代码中为xhr.status)停止jqGrid刷新.对该行的小修改jqGrid的代码将允许您在服务器上的数据不变的情况下停止jqGrid刷新.可以为"notmodified"测试textStatus(在jqGrid当前代码中为st),也可以为jqXHR.satus(在当前jqGrid代码中为xhr.status). .org/wiki/List_of_HTTP_status_codes#3xx_Redirection"rel =" nofollow noreferrer> 304 .重要的是要使用此方案,您应该使用prmNames: { nd:null }选项并设置ETagCache-Control: private, max-age=0(请参见此处此处此处有关其他信息).

The current success callback of jQuery.ajax which fill jqGrid allows you use to implement beforeProcessing callback to modify the server response, but it's not allows you to stop jqGrid refreshing based on jqXHR.satus value (it would be xhr.status in the current jqGrid code). Small modification of the line of the code of jqGrid would allows you to stop jqGrid refreshing in case of unchanged data on the server. One can either test textStatus (st in the current code of jqGrid) for "notmodified" or test jqXHR.satus (xhr.status in the current jqGrid code) for 304. It's important that to use the scenario you should use prmNames: { nd:null } option and set ETag and Cache-Control: private, max-age=0 (see here, here and here for additional information).

更新:我尝试根据我的最后建议创建演示项目,结果发现这并不像我上面描述的那么容易.尽管如此,我还是成功了.困难是因为无法从jQuery.ajax内部的服务器响应中看到304代码.原因是 XMLHttpRequest规范

UPDATED: I tried to create the demo project based on my last suggestions and found out that it's not so easy as I described above. Nevertheless I made it working. The difficulty was because one can't see the 304 code from the server response inside of jQuery.ajax. The reason was the following place in the XMLHttpRequest specification

对于由用户代理产生的 304未修改响应 生成的条件请求,用户代理必须像服务器一样 给出了包含适当内容的 200 OK 响应.用户代理 必须允许作者请求标头覆盖自动缓存 验证(例如,如果没有匹配如果已修改-自此),在这种情况下 必须通过 304未修改响应.

For 304 Not Modified responses that are a result of a user agent generated conditional request the user agent must act as if the server gave a 200 OK response with the appropriate content. The user agent must allow author request headers to override automatic cache validation (e.g. If-None-Match or If-Modified-Since), in which case 304 Not Modified responses must be passed through.

因此,在服务器响应中,在$.ajaxsuccess处理程序中看到的是 200 OK 状态,而不是 304未修改.看来XMLHttpRequest从缓存(包括所有HTTP标头)中获取的只是完整响应.因此,我决定更改缓存数据的分析,仅将最后一个HTTP响应中的ETag保存为新的jqGrid参数,并使用保存的数据测试新响应的ETag.

So one sees 200 OK status inside of success handler of $.ajax instead 304 Not Modified from the server response. It seems that XMLHttpRequest get back just full response from the cache inclusive all HTTP headers. So I decide to change the analyse of cached data just saving of ETag from the last HTTP response as new jqGrid parameter and test the ETag of the new response with the saved data.

我看到您使用PHP(我不使用:-().尽管如此,我仍然可以阅读和理解PHP代码.希望您能以相同的方式阅读C#代码并理解主要思想.因此,您将能够在PHP中实现相同的功能.

I seen that you use PHP (which I don't use :-(). Nevertheless I can read and understand PHP code. I hope you can in the same way read C# code and understand the main idea. So you will be able to implement the same in PHP.

现在,我描述我的所作所为.首先,我修改了线路的jqGrid源代码,它使用

Now I describe what I did. First of all I modified the lines of jqGrid source code which use beforeProcessing callback from

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

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

它将允许从beforeProcessing返回false以跳过数据刷新-跳过数据处理.我在演示中使用的beforeProcessing实现是基于用法ETag:

It will allows to return false from beforeProcessing to skip refreshing of data - to skip processing of data. The implementation of beforeProcessing which I used in the demo are based on the usage 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");
}

$("#isProcessed").text("Processed");或行$("#isProcessed").text("Processing skipped!!!");在div中设置了"Processed""Processing skipped!!!"文本,我曾经用这种方式直观地表明来自服务器的数据已用于填充网格.

The line $("#isProcessed").text("Processed"); or the line $("#isProcessed").text("Processing skipped!!!"); set "Processed" or "Processing skipped!!!" text in the div which I used to indicate visually that the data from the server was used to fill the grid.

在演示中我显示两个具有相同数据的网格.我用于编辑数据的第一格.第二个网格每秒提取一次来自服务器的数据.如果服务器上的数据没有更改,则HTTP流量如下所示

In the demo I display two grids with the same data. The fist grid I use for editing of data. The second grid pulls the data from the server every second. If the data are not changed on the server the HTTP traffic looks as following

HTTP请求:

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响应:

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

因此,如果未更改数据,则不会从服务器传输任何数据.如果更改了数据,则HTTP标头将从HTTP/1.1 200 OK开始,并包含ETag修改后的新数据以及数据本身的页面.

So no data will be transferred from the server if the data are not changed. If the data are changed, the HTTP header will be started with HTTP/1.1 200 OK and contains ETag of new modified data together with the page of data itself.

可以使用导航器的刷新"按钮手动刷新网格的数据,也可以使用将每秒执行$grid1.trigger('reloadGrid', [{ current: true}]);的启动自动刷新"按钮来刷新网格的数据.页面看起来像

One can refresh the data of the grid either manually using "Refresh" button of the navigator or uses "Start Autorefresh" button which will execute $grid1.trigger('reloadGrid', [{ current: true}]); every second. The page looks like

我在页面底部用颜色框标记了最重要的部分.如果选择一个loadui: "disable"选项,则在拉动服务器的过程中根本看不到网格上的任何更改.如果有人评论了一个选项,即在很短的时间内看到正在加载..." div,但没有网格将闪烁.

I marked the most important parts on the bottom of the page with the color boxes. If one loadui: "disable" option then one don't see any changes on the grid at all during the pulling of the server. If one commented the option that one will see "Loading..." div for very short time, but no grid contain will flicker.

开始自动刷新"后,大多数人会看到如下图所示的图片

After starting of "Autorefreshing" one will see mostly the picture like below

如果要更改第一个网格中的某些行,则第二个网格将在一秒钟内更改,一个人将看到"Processed"文本,此文本将在一秒钟后更改为"Processing skipped!!!"文本.

If one would change some row in the first grid, the second grid will be changed in a second and one will see "Processed" text which will be changed to "Processing skipped!!!" text in one more second.

以下是服务器端的相应代码(我使用过ASP.NET MVC)

The corresponding code (I used ASP.NET MVC) on the server side is mostly the following

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);
}

我希望对于不仅仅使用ASP.NET MVC的人,代码的主要思想也应该清楚.

I hope that the main idea of the code will be clear also for people which use not only ASP.NET MVC.

您可以在此处下载项目.

You can download the project here.

已更新:我发布了此处).因此,下一版jqGrid将包含它.

UPDATED: I posted the feature request to allow beforeProcessing to break processing of the server response by returning false value. The corresponding changes are already included (see here) in the main jqGrid code. So the next release of jqGrid will include it.

这篇关于网格中的实时数据-更好的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆