网站内容更新方案(Ajax通过定时去询问服务器是否有数据更新,怎么办?)

优采云 发布时间: 2021-10-15 00:00

  网站内容更新方案(Ajax通过定时去询问服务器是否有数据更新,怎么办?)

  Ajax定期向服务器请求数据更新,这似乎是一个通用的解决方案,比如1元xx品类的网站,因为抢购模式需要更新产品的剩余副本。比如获取服务器当前参与人数,获取最新购买次数,发送私信,好友消息,每类数据设置一个时间,如:1秒到数据库取数据。大多数请求的链接都是无效的,请求过多会导致浏览器无响应。

  二、为什么不能将两者结合起来,选择一个折衷的方案?

  客户端脚本需要一个可以通知我们服务器端有数据更新的程序,然后执行注册的程序到服务器端获取相应的数据。

  我们只需要服务端通知提供这样的数据结构:

  {

//用户消息更新时间

msg: '20141192003261234',

//网站购买记录更新时间

buy: '20141192003534567'

}

  获取客户端的当前数据后,将其与当前浏览器中存储的用户消息更新时间进行比较。如果msg更新时间和服务器给出的时间完全一致,我们就不需要去服务器去获取用户的个人消息了。相反,服务器中的消息被更新,我们开始执行我们预定的程序来获取服务器和用户收到的消息。显示给用户,并设置当前消息的更新时间。

  我们需要的就这么简单——我们需要一个通知程序来通知我们

  三、 我们需要做什么,会遇到那些问题。

  让服务器通知客户端程序数据更新显然不是很划算。我们上面讨论过,所以需要在客户端设置一个循环定时程序,从服务器获取注册类型(用户消息,网站交易次数、购买次数、剩余产品数量),通过数据类型的注册时间来决定是否执行我们注册的方法。

  问题1:定时程序必须有条不紊的执行ajax方法(上一个ajax完成后才能发送第二个ajax),服务器取数据是一个耗时的操作。

  Ajax 异步递归。

  问题二:不是每个页面都需要知道数据的变化

  在不同的页面注册不同的监控信息。

  问题三:如何动态启动和停止定时程序,并保持程序只能运行一个定时实例。

  设置互斥锁。

  问题4:服务器如何保存这些数据的更新状态(public:卷,individual:用户消息)。

  需要一个存储介质来存储对应类型信息的更新时间

  问题5:如何从异常中恢复。确保定时程序可以正常运行。

  尝试...抓住...$.ajaxerror。

  四、代码实现

  客户端计时程序:

   //客户端*敏*感*词*对象

var listener = {

tid: 0,

keys: "",

//任务存储对象

taskType: {},

//注册一个任务

appendTaskType: function (key, type) {

if (typeof (type) == "function" && typeof (key) == "string" && /^[a-z0-9]+$/.test(key)) {

//添加一个任务

this.taskType[key] = {

//任务执行函数

fun: type,

//变化量

ts: ''

};

var a = [];

for (var k in this.taskType) { a.push(k); }

this.keys = a.join('.');

}

},

//开始运行*敏*感*词*

start: function () {

//如果定时器正在运行则返回

if (this.tid != 0)

return;

fn();

//私有定时执行方法

function fn() {

$.getJSON("/api/listener", { keys: listener.keys }, function (d) {

//获取定时器所有的注册类型

for (var key in listener.taskType) {

//获取注册类型对象

var O = listener.taskType[key];

//判断当前对象是否存在和当前的值是否和之前的变化值一样,是否真正执行

if (d[key] && d[key] != O.ts) {

//更改现有状态

O.ts = d[key];

//执行注册函数

O.fun(O);

}

}

//设置ID

listener.tid = setTimeout(fn, 1000);

})

}

},

//关闭*敏*感*词*

stop: function () {

//清除定时器

clearTimeout(this.tid);

//归零

this.tid = 0;

}

}

//注册对页面的*敏*感*词*

listener.appendTaskType("msg", function () {

$.getJSON("/api/getlist", { key: 'msg' }, function (data) {

var b = $("#msgList");

b.hide();

b.empty();

var html = '';

for (var i = 0; i < data.length; i++) {

html += "【" + data[i].user + "】说:" + data[i].msg + ""

}

b.html(html);

b.slideDown(300);

})

});

//注册对购买记录的*敏*感*词*

listener.appendTaskType("buy", function () {

$.getJSON("/api/getlist", { key: 'buy' }, function (data) {

var b = $("#buyList");

b.hide();

b.empty();

var html = '';

for (var i = 0; i < data.length; i++) {

html += "【" + data[i].user + "】购买了:" + data[i].msg + ""

}

b.html(html);

b.slideDown(300);

})

})

//开始执行*敏*感*词*任务

listener.start();

  服务器代码:

  using System;

using System.Collections.Generic;

using System.Linq;

using System.Threading;

using System.Web;

using System.Web.Mvc;

namespace MvcApplication1.Controllers {

public class ApiController : Controller {

//

// GET: /Api/

///

/// 根据缓存Key获取当前缓存最后更新的标示

///

/// 缓存Key

/// 最后更新的时间

public string getlast(string cacheKey) {

List ls = HttpRuntime.Cache.Get(cacheKey) as List;

if (ls != null)

return ls.First().time;

return "0";

}

///

/// 服务器定时方法,这个方法是检测,数据有没有进行更新

///

///

public ContentResult Listener(string keys) {

if (string.IsNullOrWhiteSpace(keys))

return Content("{}");

System.Text.StringBuilder builder = new System.Text.StringBuilder("{");

//客户端需要知道用户信息是否变动

if (keys.Contains("msg")) {

builder.AppendFormat("\"msg\":\"{0}\",", getlast("msg"));

}

//客户端需要知道购买列表是否变动

if (keys.Contains("buy")) {

builder.AppendFormat("\"buy\":\"{0}\",", getlast("buy"));

}

//类推各种*敏*感*词*.......

//移除最后“,”

if (builder.Length > 1) {

builder.Remove(builder.Length - 1, 1);

}

builder.Append("}");

return Content(builder.ToString());

}

public ContentResult msg(data ms) {

InsertCache(ms, "msg");

return Content("ok");

}

public ContentResult buy(data buy) {

InsertCache(buy, "buy");

return Content("ok");

}

private void InsertCache(data d, string cacheKey) {

//使用时间设置最后更新量

d.time = DateTime.Now.ToString("yyyyMMddhhmmssffff");

//获取存储的值

List ls = HttpRuntime.Cache.Get(cacheKey) as List;

//判断是否为空

if (ls == null) {

ls = new List();

HttpRuntime.Cache.Insert(cacheKey, ls);

}

//添加到集合

ls.Insert(0, d);

//移除大于这个数

if (ls.Count > 10)

ls.RemoveRange(10, ls.Count - 10);

}

public JsonResult GetList(string key) {

if (string.IsNullOrEmpty(key))

return Json(null, JsonRequestBehavior.AllowGet);

return Json(HttpRuntime.Cache.Get(key) as List, JsonRequestBehavior.AllowGet);

}

public JsonResult GetCache() {

return Json(new {

p1 = HttpRuntime.Cache.EffectivePercentagePhysicalMemoryLimit,

p2 = HttpRuntime.Cache.EffectivePrivateBytesLimit

},

JsonRequestBehavior.AllowGet);

}

}

//定义一个数据存储介质

public class data {

public string user { get; set; }

public string msg { get; set; }

public string time { get; set; }

}

}

  请下载DEMO 点击下载

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线