7

我有一个小型 MVC 网站,供朋友美发沙龙使用。在此页面上,我有一个 div 用于显示它从数据库记录中获取的数字。这个数字是当前排队等候理发的人数。

我目前拥有的是能够登录到“管理”页面并使用表格更新此号码,从“2”到“5”,然后根据有多少人坐在里面将“5”更改为“6”这个队列。

这是目前的手动操作。代码如下:

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

控制器

[HttpPost]
        public ActionResult Update(Data data)
        {
            if (ModelState.IsValid)
            {
                data.ID = 1; //EF need to know which row to update in the database. 
                db.Entry(data).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index", "Home");
            }

            return View(data);
        }

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

型号代码

{
    public class Data
    {
        public int ID { get; set; }
        public string Queue_Number { get; set; }
    }

    public class DataDBContext : DbContext
    {
        public DbSet<Data>Queue { get; set; }
    }
}

我真正希望发生的是,一旦您从“管理”页面上的表单中手动更新队列编号,我希望自动倒计时 20 分钟(理发所需的粗略时间),然后队列编号自动向下调整 1 直到它变为“0”。

例如,我们有 5 人在排队,20 分钟后它自动调整为 4 人,网页将自动更新/刷新,然后又有 2 人走进,所以我们手动将其调整为 6 人排队,计时器开始再次,每 20 分钟通过队列调整 -1 直到它下降到“0”。一旦它达到“0”,它就会一直停留在那里,直到我们手动将更多人添加到队列中。

恐怕我什至不知道如何从这样的请求开始,或者即使有可能?

我非常感谢这里的专家提供的任何帮助,这些帮助可能能够为我“步步为营”。任何我没有提供的信息我都会努力补充——我意识到我不是最擅长解释自己的:-(

4

4 回答 4

7

你考虑过阿贾克斯吗?您是否在手动设置标志时存储上次更新时间?您可以使用 Ajax 请求同时运行使用 jquery 设置间隔。这将每 2 分钟触发一次 ajax 请求。查找上次更新的时间,如果超过 20 分钟,然后从数据库中删除一个,您的返回将是新号码,jquery 可以为您更新该号码。

实际上是一个非常简单的过程,但需要有关基础数据的更多详细信息。

这是我如何从您的问题中看到它的工作方式

在控制器中

public ActionResult ajaxUpdate()
        {
            //open connection
            dbcontext db = new dbcontext();
            db.Connection.Open();

            // get the last updated record in the database.
            var entry = db.Entry.OrderByDecending(m=> m.LastUpdatedDate).FirstOrDefault();

            //clean up
            db.Connection.Close();
            db.Dispose();

            //return -1 as error
            if(entry == null){

                return Json(-1,JsonRequestBehavior.AllowGet);

            }

            // get current number of people in queue
            Int32 numberOfPeople = entry.QueueNumber;

            TimeSpan span = DateTime.Now.Subtract(entry.LastUpdatedDate);

            if(span.Minutes >= 20){

                // if 20 mins have passed assume a person has been completed since manual update
                numberOfPeople--;

            }

            //this returns a number, alternatively you can return a Partial
            return Json(numberOfPeople, JsonRequestBehavior.AllowGet);
        }

jQuery 和 Ajax

$(document).ready(function () {

    // run function every x minutes
    setInterval(function () {
        UpdateQueue();
    }, 100000);





});
    function UpdateQueue() {

    $.ajax({
        cache: true,
        type: 'POST',
        url: "/ControllerName/ajaxUpdate",
        async: false,
        dataType: "json",
        success: function (result) {
            // on success result will be the number returned

            // -1 is error
            if (result == -1) {
                return;

            }

            // check the -- didn't return a negative
            if (result < 0) {

                result = 0;

            }

            //find your element in the HTML to update
            $('#NumberElement').text().replaceWith(result);


        }

    });


}

您必须确保在包含此代码之前包含您的 jquery 库,否则您将没有定义 Jquery。

于 2012-11-30T12:16:32.070 回答
4

我已经用一点线程为您弥补了服务器端解决方案。希望我在关键部分锁上是正确的。

它的优点是您的应用程序管理员不必挂在页面上以减少当前客户的数量(就像他应该使用 ajax 请求一样)。

这个怎么运作

在“客户数量”更新时,它正在启动(如有必要)新的倒计时线程,该线程等待(休眠)预定义的时间间隔,然后减少数量。

public class CustomerAdminService
{
    // time in milliseconds it will take to decrease number of waiting customers 
    const int sleepTime = 10000;
    // current number of customers (just for simplicity - you can have it in db or somewhere else)
    static int numberOfCustomers;

    static Thread updaterThread;

    // object lock
    static readonly object locker = new Object();

    public int GetNumberOfCustomers()
    {
        return numberOfCustomers;
    }

    public void UpdateCustomers(int value)
    {
        lock (locker)
        {
            if (updaterThread == null)
            {
                //start new downcounting thread
                updaterThread = new Thread(new ThreadStart(UpdateWorker));
                updaterThread.Start();
            }
            SetNumberOfWaitingCustomers(value);
        }
    }

    private void SetNumberOfWaitingCustomers(int value)
    {
        numberOfCustomers = value;
    }

    // downcounting thread method
    private void UpdateWorker()
    {      
        while (true)
        {
            // sleep for predefined time
            Thread.Sleep(sleepTime);
            lock (locker)
            {              
                var number = GetNumberOfCustomers();             
                if (number <= 1)
                {
                    // if number of currents customers is now zero - end the downcounting thread
                    SetNumberOfWaitingCustomers(0);
                    updaterThread = null;
                    return;
                }
                SetNumberOfWaitingCustomers(number - 1);
            }
        }
    }
}

评论:您可以考虑将 jQuery 用于一些计时器倒计时脚本。显示类似:您可以在 40 分钟内送达 ;-)

于 2012-12-06T23:55:14.730 回答
1

是的,Ajax 是关键。您的网站可以使用它与您的服务器进行不明显的通信。

于 2012-12-10T08:27:58.287 回答
1

另一种方法是不更新数据库中的计数,而是简单地使用查询来确定特定时间段内的客户数量。您可以通过修改模型来代替QueueNumber它使用到达时间并更改控制器以插入新的数据记录来做到这一点。

{
    public class Data
    {
        public int ID { get; set; }
        public DateTime Arrival_Time { get; set; }
    }

    public class DataDBContext : DbContext
    {
        public DbSet<Data> Queue { get; set; }
    } 
}

这样,正如其他人建议的那样,您可以使用 AJAX 来轮询队列中的人数,控制器操作可能如下所示:

[HttpGet]
public ActionResult NumberOfPeopleInQueue()
{
    var result = db.NumberOfCustomersSince(DateTime.Now.AddMinutes(-20));
    return Json(result);
}

这种方法的好处是,如果理发开始需要更长的时间(比如 30 分钟),您可以简单地更改查询并且应用程序继续工作。

于 2012-12-10T08:59:54.433 回答