Gå til innhold

Anbefalte innlegg

Hei!

 

TLDR; Finnes det en måte å kjøre et skript som kjører oppdateringer på databasen på Server Siden, uavhengig av at brukere er inne på siden?

 

Vi holder på å planlegge et prosjekt innen et fag hvor vi skal kode i ASP.net og C#. (Mulig denne tråden da hører inne under kategorien .NET programering, i så fall, beklager)

 

Så langt har vi tenkt litt på ideen om å gjøre noe annet enn det vanlige, som har vært å lage en webshop, for å prøve å lage et enkelt Web-Browser spill, da noe lignende Travian eller andre lignende tekst baserte spill.

 

Lurer derfor på hvorvidt det finnes noen måte å ta tiden i "real-time" på, altså, dersom man starter byggingen av en bygning i spillet, så skal den etter 10 minutter bli ferdig og da dataene oppdatert i databasen, uavhengig om brukeren har lukket ned browseren.

 

Har sett på mulighet for å ikke ta tiden, og heller bruke "turns" hvor ting som f.eks. bygging av bygninger skjer med en gang, hvor man heller kan bruke et visst nummer med "turns" på en handling, som visst nok kunne kodes ved hjelp av "Global" filen. Da sette denne til å gi en turn hver time, halvtime, eller hva enn man ønsker.

 

Håper problemet er relativt forståelig. Finnes det noen gode løsninger til dette, evt. gi en link til noe informasjon angående slik tidtakning eller server side oppdatering med bestemt intervall.

 

Vet at å lage et slikt spill i ASP.net antageligvis er mye mer tungvindt enn PhP, men nå er det slik at faget er ASP.net, så det hadde jo vært moro å prøve.

 

På forhånd takk :)

Endret av Cemi
Lenke til kommentar
Videoannonse
Annonse

Nå er det ingen grunn til at det skulle være mer tungvindt med asp.net enn med php, men jeg lar den ligge for å unngå en evt flamewar...

 

Uten at jeg har gjort så mye research på dette selv så kan jeg se for meg at en Bygning kan ha en verdi som sier når byggingen ble startet. Og hvis "nå" er over x antall minutter etter byggestart, så er bygningen ferdig.

 

-C-

Lenke til kommentar

Mye mulig, har bare fått den forståelsen når jeg har googlet rundt på varierte sider og tutorials som omhandler slike browser games.

 

Å lagre verdien for når den er ferdig er forsåvidt ikke noe problem. Problemet er å få serveren til å koninuerlig sjekke om den er ferdig?

 

Dersom man bare kan sjekke hvorvidt den er ferdig når brukeren laster en ny side på spillet, så vil man ikke kunne starte å bygge noe, og så blir det ferdig når det skal være ferdig.

 

Dette problemet angår også tildeling av ressurser som gjerne skulle skje fortløpende istedefor når brukeren logger inn sammenlignet med forrige gang han logget inn.

 

Er vel egentlig ute etter om det er noen måte å skrive slike skript som kan ligge å kjøre på serveren? :)

 

Ellers takk for svar.

Lenke til kommentar

Er vel egentlig ute etter om det er noen måte å skrive slike skript som kan ligge å kjøre på serveren? :)

 

Enten kan du ha et script som kjører kontinuerlig (blir i PHP da jeg er usikker på syntaxen) :

while(TRUE) {
 // Do stuff.
 sleep(1); // Take a break.
}

 

Eller så kan du vel bruke "planlagte oppgaver" til å kjøre et script hvert minutt eller noe.

 

Du kan og gjøre det på alle requests, ikke bare de som tilhører den brukeren som bygger. Men da bør du ha noe form for å regne hvor lenge siden det egentlig var ferdig og tildele ressurser avhengig av det.

Lenke til kommentar
  • 2 uker senere...

Da tror vi at vi har funnet en løsning, som ligner relativt mye på den siste. Vi har sett på Cron jobs og Powershell, men har egentlig ikke blitt så mye klokere på dem foreløpig.

 

Vi tenker å ha en side som inneholder

 

      <asp:ScriptManager ID="ScriptManager1" runat="server">
       </asp:ScriptManager>
       <asp:Timer ID="Timer1" runat="server" Interval="10000" ontick="Timer1_Tick">
      // Eventuelt endre interval verdien for lengre (eller kortere) "ticks".
       </asp:Timer>

 

Og da i Timer1_Tick så kjøres en dekrementer alle verdiene "ticks" i en kø av hendelser. Istedefor å kjøre det på sekunder etc så tar ting man kan gjøre et bestemt antall "tick". Og dersom det når 0 så oppdaterer den da den relevante verdien.

 

Noen som har noen idé om dette vil funke? Vi har bare sett at det funker når vi tester det med en og en verdi, men er jo usikker dersom det blir 10-20 oppgaver i køen som skal oppdateres og sjekkes om de er 0, om det vil gå for tregt.

 

Takker for svar :)

Lenke til kommentar

Stemmer det, men vi tenker ikke å ha den i siden til spilleren. Vi tenker at det muligens vil være mulig å ha siden åpen på server maskinen. Er litt usikker på hvordan hosting av slike applikasjoner vil fungere, og om det faktisk er mulig :)

 

Har særdeles liten erfaring med hvordan servere fungerer foreløpig.

Lenke til kommentar

Du kan jo laste ned f.eks MyPhpPA.

 

Det er et ferdig browser game med ticker som du kan se på hvordan den er bygget opp, selve spillet er i php så kanskje ikke så relevant men tickeren er bra eksempel.

 

Den er ment for og kjøre på linux, det er da en applikasjon som i korte trekk gjør følgende:

1 - kjører heftig mye sql spørringer for og oppdatere alt av bygginger,kriging etc

2 - Øke tick counter med 1

3 - sleep i 60sec til neste oppdatering/tick

4 - kontrollere om runden er ferdig, er runden f.eks 10 000ticks så om tick >10000 avslutt programmet.

5 - om tick <10000 tilbake til 1

 

Har også sett enkelte løse det med og bruke et script som bare kjører steg 1-4 så avslutte uansett så legge inn cron jobs/schedueled tasks for og starte alle oppdateringene.

Men er selv mer fan av den første.

 

Husk skal du kjøre flere runder/tickers samtidig så er det lurt spre oppdateringene så en oppdaterer xx:xx:10 neste xx:xx:20 så neste xx:xx:30 etc

Istedenfor og kjøre alt xx:xx:00 og risikere treig kjøring for så la servern stå idle i 60sec til neste.

 

 

Jeg har kjørt flere tusen runder med denne tickeren uten at den noensinne har hengt seg opp etc

Største antallet spillere jeg har kjørt samtidig er vel rundt 1400stk på en core2duo maskin hvor 800 av de oppdatert annenhvert sekund.

i ene ticker filen har du hele prosedyren som du kan åpne rett i notepad med hvordan kjøringene/oppdateringene er strukturert.

Endret av cruzader
  • Liker 1
Lenke til kommentar

Takker for alle svar.

 

Jeg tror jeg har noe som, ihvertfall når jeg tester det på en helt basic operasjon, fungerer. Jeg skjønner derimot ikke helt hvorfor, og er ute etter en liten forklaring dersom det finnes :)

 

Jeg har laget en tråd, og kjører tråden i global.asax application start. Det eneste jeg ikke skjønner er hvorfor den kjører hvert 10. sekund? Jeg har ikke lagt inn noe tidtaking enda, og skulle bare sjekke, men den ser ut til å kjøre akkurat hvert 10. sekund. Er dette noe default i C# eller noe slikt?

 

Koden ser foreløpig slik ut (ser i ettertid at spesielt siste ble litt rotete, men SQL statementene er antageligvis ikke så viktige ang. spørsmålet, har derfor tatt dem ut og bare skrevet hva de gjør dersom det skulle være relevant.):

 

Global.asax

protected void Application_Start(object sender, EventArgs e)
       {
           onTick ticker = new onTick();
           Thread tickThread = new Thread(new ThreadStart(ticker.Tick));
           tickThread.Start();
           Thread.Sleep(1);
           tickThread.Abort();
           tickThread.Join();
           try
           {
               tickThread.Start();
           }
           catch (ThreadStateException)
           {
           }
       }

 

Ticker class:

public class onTick{

   public void Tick()
   {
           //sqlConnection myCon.
           //decrementCom som dekrementeterer alle ticks verdier.
           //updateCom som utfører ferdige kø-elementer.
           //deleteCom som sletter ferdige kø-elementer.
           try
           {
               myCon.Open();
               decrementCom.ExecuteNonQuery();
               updateCom.ExecuteNonQuery();
               deleteCom.ExecuteNonQuery();
           }
           finally
           {
               myCon.Close();
           }
   }

}

Endret av Cemi
Lenke til kommentar

Thread.Abort er ikke spesielt nice å kalle.

 

Uten å ha testet koden din vil jeg anta at det kastes et eller annet exception på andre tickThread.Start() statement siden en tråd som er ferig å kjøre kan ikke startes igjen. Kan også være du får noe ThreadAbortException fra Abort/Join kombinasjonen din som kaster app poolen inn i en restart loop. Det er ikke noe loop i koden din, så etter Applicatoin_Start er det ingen user threads i live, og IIS vil kunne stoppe applikasjonen din for å spare resurser, og så starte den igjen når det er nødvendig, det vil trigge Application_Start igjen, så du må sørge for å ha en tråd i gang så det ikke skjer.

 

Jeg ville kanskje begynt med noe sånt:

 

Ticker/game loop klasse. Denne er en Singleton, slik at alle får tak i samme instans av "spillet" (Singleton biten av det burde selvfølgelig ligget i et factory/ioc pattern, men jeg gidder ikke det i et lite eksempel. )

   public class Ticker
   {
       private static Ticker _globalInstance;

       private volatile bool _running;

       public int Count { get; set; }

       private Ticker() { }

       public void Start(int delay)
       {
           _running = true;

           while(_running)
           {
               Thread.Sleep(delay);
               Tick();
           }
       }

       public void Tick()
       {
           Count++;
       }

       public void Stop()
       {
           _running = false;
       }

       public static Ticker GetGlobalInstance()
       {
           if(_globalInstance==null)
               _globalInstance = new Ticker();

           return _globalInstance;
       }
   }

 

Så starter vi sakene i Application_Start, og kjører f.eks ett tikk i sekundet:

       void Application_Start(object sender, EventArgs e)
       {
           var ticker = Ticker.GetGlobalInstance();
           Action job = () => ticker.Start(1000);
           job.BeginInvoke(null, null);
       }

 

Så kan view'ene polle tilstand fra Singleton-instansen

<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
   <p>
       Game has lasted <%= Ticker.GetGlobalInstance().Count %> turns.
   </p>
</asp:Content>

Endret av MailMan13
  • Liker 1
Lenke til kommentar

Jeg er ikke helt med på hva du mener. Koden fungerer, og den teller ned ticks selv om jeg ikke har oppe noen sider når jeg kjører den.

 

Fulgte bare eksempelet på msdn siden for threading, og det ser ut til å fungere flott.

 

Det eneste jeg ikke skjønner er hvorfor det skjer hvert 10. sekund, og hvordan jeg evt. kan endre denne tidtakingen?

 

Da jeg ville trodd ut i fra koden, at den bare ville telle ned til 0 med en gang, da den eneste sleep som kalles er 1 milisekund.

 

Mange takk for svar uansett.

Lenke til kommentar

Det er ingenting i koden din som teller ned mer enn en gang. Du starter tråden èn gang, som dekrementerer telleren i databasen èn gang, så kaller du tickThread.Start() en gang til, som vil gi et ThreadStateException og gjøre ingenting.

 

At det kjører flere ganger er fordi applikasjonen blir resirkulert i app poolen av en eller annen grunn.

  • Liker 1
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...