7

Ho un piccolo sito Web MVC che è per un parrucchiere di amici. In questa pagina ho un div che viene utilizzato per visualizzare un numero che prende da un record del database. Questo numero è il numero corrente di persone sedute in coda in attesa di un taglio di capelli.Timer conto alla rovescia automatico per regolare il record del database

Quello che ho attualmente è la possibilità di accedere a una pagina "admin" e aggiornare questo numero utilizzando un modulo, da dire "2" a "5", quindi cambiare "5" a "6" a seconda di quanti le persone sono sedute in questa fila.

Questa è un'operazione manuale così com'è attualmente. Codice è qui sotto:

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

controller

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

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

codice modello

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

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

Quello che ho piacerebbe davvero che succedesse è che una volta aggiornato manualmente il numero di coda dal for Nella pagina "admin" mi piacerebbe un conto alla rovescia automatico di 20 minuti (il tempo approssimativo necessario per il taglio di capelli) e quindi il numero di coda si regola automaticamente di uno fino a che non arriva a "0".

ad es. Abbiamo 5 persone in coda, 20 minuti dopo è regolato automaticamente a 4 persone e la pagina web si aggiornerà/rinfresca automaticamente, quindi entrano altre 2 persone, quindi la aggiustiamo manualmente a 6 persone nella coda e il timer ricomincia , ogni 20 minuti passa la coda viene regolata di -1 finché non scende a "0". Una volta che arriva a "0" rimane lì fino a quando non aggiungiamo manualmente più persone alla coda.

Ho paura di non avere idea di come iniziare nemmeno con una simile richiesta, o anche se è possibile?

Sarei davvero grato per qualsiasi aiuto da parte degli esperti qui che potrebbe essere in grado di "babysitter" per me. Qualsiasi informazione che non ho fornito cercherò di aggiungere - Mi rendo conto di non essere il migliore a spiegarmi :-(

risposta

7

Hai considerato Ajax? Stai memorizzando l'ultima volta aggiornata impostando manualmente la bandiera? È possibile utilizzare la richiesta Ajax per eseguire simultaneamente l'intervallo jquery Set. Che attiverà la richiesta ajax ogni 2 minuti. Trova l'ultima volta che è stato aggiornato, se viene passato 20 minuti, quindi rimuovilo dal database, il tuo ritorno sarebbe il nuovo numero e jquery possono aggiornare quel numero per voi.

Piuttosto un semplice processo in realtà, ma hanno bisogno di maggiori dettagli sui dati sottostanti.

Ecco come posso vederlo lavorare dal Questio n

controller

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


     } 

    }); 


} 

È necessario assicurarsi di includere le librerie jQuery prima di includere questo codice o si avrà Jquery non definito.

+0

Grazie Craig, non ho preso in considerazione l'Ajax, principalmente perché ho appena iniziato a utilizzare MVC e non ho alcun background di codifica, quindi non avrei la minima idea da dove cominciare. Apprezzo comunque la risposta. Non ho ancora avuto alcuna idea su come affrontare questo problema, parte della domanda era quella di ottenere idee su quale sarebbe stata una buona idea su come ottenere ciò che voglio. Attualmente sto memorizzando solo il numero di coda nel database, nient'altro. – Harry

+2

@Harry Cerca di memorizzare l'ora e poi usa jquery e Ajax per aggiornare il numero senza alcun aggiornamento. C'è molta documentazione su Ajax e esempi di codice. Aggiornerò la risposta per farti andare. – CR41G14

+0

Grazie Craig, inizierò a cercare anche Ajax. Apprezzo il tuo aiuto, grazie ancora. – Harry

4

Ho risolto la soluzione lato server con un po 'di threading.Spero di essere corretto sulle serrature delle sezioni critiche.

Ha un vantaggio che l'amministratore dell'applicazione non deve aggrapparsi alla pagina per ottenere il numero di clienti attuali conteggiati (come dovrebbe con richieste Ajax).

Come funziona

Su 'numero di clienti' aggiornamento sta cominciando (se necessario) nuovo thread conto alla rovescia, che attende (pl) per l'intervallo predefinito e quindi diminuisce il numero.

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

Commento: è possibile considerare l'utilizzo di jQuery per un po 'il timer di script down-conteggio. Qualcosa del tipo: Puoi essere servito in 40 minuti ;-)

1

Sì, Ajax è la chiave. Può essere utilizzato dal tuo sito Web per comunicare in modo impercettibile con il tuo server.

1

Un approccio alternativo sarebbe quello di non aggiornare il conteggio nel database ma semplicemente utilizzare una query per determinare il numero di clienti entro un determinato periodo di tempo. È possibile farlo modificando il modello in modo che invece di QueueNumber utilizzi un orario di arrivo e modificando il controller in modo che inserisca un nuovo record di dati.

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

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

In questo modo, come altri hanno suggerito è possibile utilizzare AJAX per il polling per il numero di persone in coda con un'azione di controllo che potrebbe essere simile a questa:

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

La cosa bella questo approccio è che se i tagli di capelli iniziano a richiedere più tempo (ad esempio 30 minuti), è sufficiente modificare la query e l'applicazione continua a funzionare.

Problemi correlati