[php, ajax, mysql] betrouwbaar wegschrijven naar database

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Millshot2
  • Registratie: Februari 2006
  • Laatst online: 13-10-2022
Beste Tweakers,

Hopelijk wordt dit een interessant topic waar niet alleen ikzelf maar ook anderen iets aan zullen hebben. De openingspost zal een vrij lang verhaal zijn met relatief weinig code. Relevante stukken code hoop ik toch mee te posten en kan ik altijd in een vervolg post nog uitbreiden. Hopelijk open ik een topic op de juiste locatie (web of prog?). Uiteraard heb ik veel gezocht op internet op php en javascript om toetsenbord acties naar een mysql database te krijgen.

Dinsdag 13 januari is er een biljarttoernooi in Nederland die ik met eigengemaakte software zal gaan ondersteunen om de score live via internet te tonen. Er hangen camera's en er wordt ook live via internet uitgezonden. Daar hoef ik me verder geen zorgen om te maken. Ik ontvang een mms link en die plaats ik in mijn mysql database en that's it.

Afgelopen zaterdag heb ik een test gehad met een ander biljartevenement om te kijken of mijn software goed draait. Thuis werkt het namelijk perfect. Mijn scoring systeem viel echter tegen. Dat zal ik even uitleggen.

De huidige situatie is als volgt. Er is een internetsite (vb. www.domein.nl/schrijfpartij.php?partij=12) die geopend wordt op locatie waar gebiljart wordt. Op de pagina wordt netjes een scorebord getoond, met speler A tegen speler B, de punten die gehaald moeten worden etc.

De body tag heeft een onload dat bij een OnKeyPress een javascript functie gedraaid moet worden.
Op het moment dat de schrijver van een partij, op zijn laptop op de letter X drukt, komt er bij de speler die aan zet is, een carambole bij. Dat zijn simpele div's die gewoon verhoogd worden. In dezelfde javascript wordt de source van een verborgen iframe verandert in een php pagina, zodat de ophoging van de punten in de database wordt weggeschreven. Bij mij thuis bleek deze aanpak goed te werken. Alle toetsenbord acties die ik had ingesteld, werden goed verwerkt via een klein iframe naar de database. Op een internetsite toegankelijk voor het grote publiek was een stream ge-embed en een scorebord te zien.

Het scorebord voor het publiek wordt 1x per 20 seconden geladen door 1 simpele query uit te voeren.
Het scorebord wordt namelijk 1x per 20 seconden door een scriptje op de server gegenereerd, en in een simpele tabel met 2 velden gezet, zodat niet honderden bezoekers hetzelfde scorebord gaan genereren.

In theorie werkt het allemaal, maar in de praktijk bleek het anders. Het schrijven van de partij gebeurd op verschillende laptops. Ik kan afdwingen dat ze allemaal internet explorer gebruiken, anders zou de onload en onkeypress functie niet eens werken. Vanuit het hotel waar gespeeld werd, werd iedere actie op het toetsenbord naar internet geschreven. Hier ging af en toe wat fout (javascript gaf de melding toegang geweigerd voor de iframe) met als gevolg, dat de score niet naar de database kon komen. Ook werd het iframe zovaak aangeroepen (X inhouden bij grote score) dat er lege queries in de proceslijst van de database terecht kwam die gingen slapen. De database moest dus op een gegeven moment herstart worden.

Mijn aanpak van iedere actie naar internet is dus geen optie. Thuis in m'n eentje werkt het allemaal leuk, maar in de praktijk zullen meerdere partijen via een laptopje geschreven worden en zijn er duizenden bezoekers per dag.

Nu heb ik dus op een desktop pc WAMP geinstalleerd en draait daar lokaal een versie van mijn software.
Op locatie heb ik dus vanaf nu een servertje draaien en alle laptops zullen naar deze lokale url gaan om partijen te schrijven. De server zal 1x per zoveel seconde een scorebordje genereren en dit 1x per zoveel seconde overzetten naar een database op internet. Bezoekers via internet hebben dan live score en live beeld.

In plaats van een actie per toetsenbord tik, naar een iframe, heb ik nu een javascript functie gemaakt die via ajax (prototype) 1x per seconde de volledige inhoud van de relevante div's in het scorebord, naar een php bestand brengt. Dit werkt al wat beter, maar ook nog niet optimaal.

Ook komen er in het lokaal digitale scoreborden te hangen die bijvoorbeeld 1x per seconde de stand van de lokale server opvragen. Omdat het lokaal is, is dat allemaal nog wel te doen.

Nu ben ik echter nog op zoek naar een heel betrouwbare methode/techniek om partijen via toetsenbord acties, en hopelijk met php, javascript, html, te kunnen schrijven en het liefst onafhankelijk van browser, naar de database.

Als de score eenmaal betrouwbaar en snel naar de database gaat, dan kan ik die lokaal gewoon snel uitlezen en 1x per halve minuut ofzo synchroniseren met internet. Hopelijk komen we samen met een goede aanpak. Ik hoef geen uitgewerkt script te hebben maar hopelijk zijn er betere manieren om dit aan te pakken en uit te werken. Het is super belangrijk dat de partijen die geschreven worden via een laptop, draadloos naar een router en dan naar een lokale pc zeer betrouwbaar in een lokale database komen. Als dat lukt kan ik zoals gezegd synchroniseren met internet en in het lokaal via het netwerk snel scoreborden tonen.

Hier nog wat code.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
<body onKeyPress="doKey(window.event.keyCode)">

<form method="post" action="" name="f">
<input type="hidden" name="beziga" value="Ja" size="3" />
<input type="hidden" name="bezigb" value="" size="3" />

<table width="100%" border="0" cellspacing="0" cellpadding="3">
  <tr>
    <td align="center" valign="top">
    <b>SCHRIJVEN</b>
    
        <table border="0" cellspacing="0" cellpadding="3" style="border-top:1px solid #666666; border-left:1px solid #666666; border-right:1px solid #666666; background-color:#FFFFFF;">
          <tr>
            <td valign="top" style="border-right:1px solid #333333;">
            
                <table border="0" cellspacing="0" cellpadding="3">
                  <tr>
                    <td align="left" colspan="4" style="border-bottom:1px solid #333333;">
                        <table width="100%" border="0" cellspacing="0" cellpadding="3">
                          <tr>
                            <td width="13"><div id="begin_a" align="left"><img src="images/ball.gif" alt="" /></div></td>
                            <td><b>Jean Paul de Bruijn</b></td>
                          </tr>
                        </table>
                    </td>
                  </tr>
                  <tr>
                    <td>temaken</td>
                    <td>gemaakt</td>
                    <td>serie</td>
                    <td>moy</td>
                  </tr>
                  <tr>
                    <td>100</td>
                    <td><div id="spelera">0</div></td>
                    <td><div id="ec_spelera">0</div></td>
                    <td><div id="moy_spelera">0.000</div></td>
                  </tr>
                </table>
        
            
            </td>
            <td valign="top" style="border-right:1px solid #333333;">
            
                <table width="100%" border="0" cellspacing="0" cellpadding="6">
                  <tr>
                    <td style="border-bottom:1px solid #333333;"><b>Brt</b></td>
                  </tr>
                  <tr>
                    <td align="center"><div id="brt">0</div></td>
                  </tr>
                </table>
        
            
            </td>
            <td valign="top">
            
                <table border="0" cellspacing="0" cellpadding="3">
                  <tr>
                    <td align="left" colspan="4" style="border-bottom:1px solid #333333;">
                        <table width="100%" border="0" cellspacing="0" cellpadding="3">
                          <tr>
                            <td width="13"><div id="begin_b" align="left"></div></td>
                            <td><b>Micha van Bochem</b></td>
                          </tr>
                        </table>
                    </td>
                  </tr>
                  <tr>
                    <td>temaken</td>
                    <td>gemaakt</td>
                    <td>serie</td>
                    <td>moy</td>
                  </tr>
                  <tr>
                    <td>100</td>
                    <td><div id="spelerb">0</div></td>
                    <td><div id="ec_spelerb">0</div></td>
                    <td><div id="moy_spelerb">0.000</div></td>
                  </tr>
                </table>
            
            </td>
          </tr>
          <tr>
            <td colspan="3" style="border-top:1px solid #333333;border-bottom:1px solid #666666;">
                <font size="1"><b>
                    Z = -1 &nbsp;&nbsp;&nbsp;&nbsp; X = +1 &nbsp;&nbsp;&nbsp;&nbsp; Enter = speler &amp; brt wissel &nbsp;&nbsp;&nbsp;&nbsp; M = brt +1 &nbsp;&nbsp;&nbsp;&nbsp; N = brt -1
                </b></font>
            </td>
          </tr>
         </table>
         
         <div style="height:15px;"></div>
         
         <table border="0" cellspacing="0" cellpadding="3" align="center">
          <tr>
            <td colspan="2">
                                                <a href="index.php?page=beheer_schrijven&eid=1&id=17&s=2">
                    <b><font size="2">Partij gespeeld verklaren</font></b>
                </a>
                &nbsp;&nbsp;&nbsp;
                                                <a href="index.php?page=beheer_schrijven&eid=1&id=17&s=0">
                    <b><font size="2">Partij terug naar schema</font></b>
                </a>
                &nbsp;&nbsp;&nbsp;
                                <a href="index.php?page=beheer_schrijven&eid=1&id=17&reset=ja&partij_id=14" onClick="confirm('Weet u zeker dat u deze partij wilt resetten?')">
                    <b><font size="2">Reset</font></b>
                </a>
            </td>
          </tr>
          <tr><td colspan="2"><hr size="1" /></td></tr>
          <tr>
                        <td>
                <form method="post" action="" name="start_f">
                Tijdstip start partij<br />
                <input type="text" name="start" id="start1" size="30" maxlength="30"  value="2009-01-03 17:44:57" />
                <a href="javascript:NewCal('start1','ddmmmyyyy',true,12)"><img src="images/cal.gif" width="16" height="16" border="0" alt="Pick a date"></a><br />
                <input type="submit" name="submit" value="Start markeren" />
                </form>
            </td>
            <td>
                <form method="post" action="" name="stop_f">
                Tijdstip start partij<br />
                <input type="text" name="stop" id="stop1" size="30" maxlength="30" style="color:#CC0000;" value="2009-01-05 12:48:48" />
                <a href="javascript:NewCal('stop1','ddmmmyyyy',true,12)"><img src="images/cal.gif" width="16" height="16" border="0" alt="Pick a date"></a><br />
                <input type="submit" name="submit" value="Stop markeren" />
                </form>
            </td>
          </tr>
        </table>

    
    </td>
  </tr>
</table>
</form>

<iframe name="bewaarframe" src="" height="0" width="0" frameborder="0"></iframe>
<iframe name="bewaarframe2" src="" height="0" width="0" frameborder="0"></iframe>
<iframe name="bewaarframe3" src="" height="0" width="0" frameborder="0"></iframe>
<iframe name="bewaarframe4" src="" height="0" width="0" frameborder="0"></iframe>
<iframe name="bewaarframe5" src="" height="0" width="0" frameborder="0"></iframe>
<iframe name="bewaarframe6" src="" height="0" width="0" frameborder="0"></iframe>
<iframe name="bewaarframe7" src="" height="0" width="0" frameborder="0"></iframe>

<script type="text/JavaScript">
<!-- 
function doKey($key) {
  
  var url = '';
  var pars = '';
  var myAjax = '';
  
  // ENTER = wissel
  if ($key == 13) {
      if (document.f.beziga.value == 'Ja') {
        document.f.beziga.value = '';
        document.f.bezigb.value = 'Ja';
        
        document.getElementById("begin_a"). innerHTML = '&nbsp;'; 
        document.getElementById("begin_b"). innerHTML = '<img src="images/ball.gif" alt="Aan tafel" />';
        
        window.frames.bewaarframe.document.location = '../ajax/update_match.php?speler=spelera_aantafel&value=n&p=14';
        window.frames.bewaarframe2.document.location = '../ajax/update_match.php?speler=spelerb_aantafel&value=j&p=14';
        document.getElementById("spelera").innerHTML = parseInt(document.getElementById("spelera").innerHTML) + parseInt(document.getElementById("ec_spelera").innerHTML);
        window.frames.bewaarframe7.document.location = '../ajax/update_match.php?&speler=spelera&p=14&value='+ parseInt(document.getElementById("spelera").innerHTML);
        document.getElementById("ec_spelera").innerHTML = 0;
        document.getElementById("ec_spelerb").innerHTML = 0;
        
        window.frames.bewaarframe3.document.location = '../ajax/update_match.php?&speler=spelera_ec&value=0&p=14';
        window.frames.bewaarframe4.document.location = '../ajax/update_match.php?&speler=spelerb_ec&value=0&p=14';
        document.getElementById("brt").innerHTML = parseInt(document.getElementById("brt").innerHTML) + 1;
        window.frames.bewaarframe5.document.location = '../ajax/update_match.php?speler=brt&p=14&value='+ parseInt(document.getElementById("brt").innerHTML);
        // punten van A schrijven test2
        window.frames.bewaarframe6.document.location = '../ajax/update_match2.php?&speler=a&p=14&value='+ parseInt(document.getElementById("spelera").innerHTML) +'&value3='+ parseInt(document.getElementById("ec_spelera").innerHTML) +'&value2='+ parseInt(document.getElementById("brt").innerHTML);
      } else {
        document.f.beziga.value = 'Ja';
        document.f.bezigb.value = '';
        
        document.getElementById("begin_a"). innerHTML = '<img src="images/ball.gif" alt="Aan tafel" />'; 
        document.getElementById("begin_b"). innerHTML = '&nbsp;'; 
        
        window.frames.bewaarframe.document.location = '../ajax/update_match.php?speler=spelera_aantafel&value=j&p=14';
        window.frames.bewaarframe2.document.location = '../ajax/update_match.php?speler=spelerb_aantafel&value=n&p=14';
        document.getElementById("spelerb").innerHTML = parseInt(document.getElementById("spelerb").innerHTML) + parseInt(document.getElementById("ec_spelerb").innerHTML);
        window.frames.bewaarframe7.document.location = '../ajax/update_match.php?&speler=spelerb&p=14&value='+ parseInt(document.getElementById("spelerb").innerHTML);
        
        document.getElementById("ec_spelera").innerHTML = 0;
        document.getElementById("ec_spelerb").innerHTML = 0;
        
        window.frames.bewaarframe3.document.location = '../ajax/update_match.php?&speler=spelera_ec&value=0&p=14';
        window.frames.bewaarframe4.document.location = '../ajax/update_match.php?&speler=spelerb_ec&value=0&p=14';
        window.frames.bewaarframe5.document.location = '../ajax/update_match2.php?&speler=b&p=14&value='+ parseInt(document.getElementById("spelerb").innerHTML) +'&value3='+ parseInt(document.getElementById("ec_spelerb").innerHTML) +'&value2='+ parseInt(document.getElementById("brt").innerHTML);
      }
  } else {
    // X = plus
    if ($key == 120) {
        if (document.f.beziga.value == 'Ja') {
            // Speler A is bezig.
            if ( ( parseInt(document.getElementById("spelera").innerHTML) + parseInt(document.getElementById("ec_spelera").innerHTML) ) < 100) {
                document.getElementById("ec_spelera").innerHTML = parseInt(document.getElementById("ec_spelera").innerHTML) + 1;
                window.frames.bewaarframe2.document.location = '../ajax/update_match.php?&speler=spelera_ec&p=14&value='+ parseInt(document.getElementById("ec_spelera").innerHTML);
            }
        } else {
            // Speler B is bezig.
            if (parseInt(document.getElementById("spelerb").innerHTML) < 100) {
                document.getElementById("ec_spelerb").innerHTML = parseInt(document.getElementById("ec_spelerb").innerHTML) + 1;
                window.frames.bewaarframe.document.location = '../ajax/update_match.php?&speler=spelerb&p=14&value='+ parseInt(document.getElementById("spelerb").innerHTML);
                window.frames.bewaarframe2.document.location = '../ajax/update_match.php?&speler=spelerb_ec&p=14&value='+ parseInt(document.getElementById("ec_spelerb").innerHTML);
            }
        }
    } else {
        // Z = min
        if ($key == 122) {
            if (document.f.beziga.value == 'Ja') {
                // Speler A is bezig.
                if (parseInt(document.getElementById("spelera").innerHTML) >= 0) {
                    document.getElementById("ec_spelera").innerHTML = parseInt(document.getElementById("ec_spelera").innerHTML) - 1;
                    window.frames.bewaarframe2.document.location = '../ajax/update_match.php?&speler=spelera_ec&p=14&value='+ parseInt(document.getElementById("ec_spelera").innerHTML);
                }
            } else {
                // Speler B is bezig.
                if (parseInt(document.getElementById("spelerb").innerHTML) >= 0) {
                    document.getElementById("ec_spelerb").innerHTML = parseInt(document.getElementById("ec_spelerb").innerHTML) - 1;
                    window.frames.bewaarframe2.document.location = '../ajax/update_match.php?&speler=spelerb_ec&p=14&value='+ parseInt(document.getElementById("ec_spelerb").innerHTML);
                }
            }
        } else {
            // N = beurt min 1
            if ($key == 110) {
                if (parseInt(document.getElementById("brt").innerHTML) > 0) {
                    document.getElementById("brt").innerHTML = parseInt(document.getElementById("brt").innerHTML) - 1;
                    window.frames.bewaarframe.document.location = '../ajax/update_match.php?speler=brt&p=14&value='+ parseInt(document.getElementById("brt").innerHTML);
                }
            } else {
                // M = beurt plus 1
                if ($key == 109) {
                    document.getElementById("brt").innerHTML = parseInt(document.getElementById("brt").innerHTML) + 1;
                    window.frames.bewaarframe.document.location = '../ajax/update_match.php?speler=brt&p=14&value='+ parseInt(document.getElementById("brt").innerHTML);
                } else { 
                    //alert("You just pressed a key: " + $key);
                }
            }   
        }
    }  
  }
   
  // Moyenne
  if (parseInt(document.getElementById("brt").innerHTML) == 0) {
    var brt = 1;
  } else {
    var brt = parseInt(document.getElementById("brt").innerHTML);
  }
  document.getElementById("moy_spelera").innerHTML = (parseInt(document.getElementById("spelera").innerHTML) / brt).toFixed(3);
  document.getElementById("moy_spelerb").innerHTML = (parseInt(document.getElementById("spelerb").innerHTML) / brt).toFixed(3);
  
}

-->
</script>

Acties:
  • 0 Henk 'm!

  • mr_derk
  • Registratie: September 2005
  • Laatst online: 24-09 21:08
waarom staat je javascript niet tussen <head> tags?, al gedebugd in verschillende browsers? bovendien vind ik jouw constructie met verborgen iframes wat krom. Wat is volgens jouw ajax? ik zie alleen javascript..

[ Voor 77% gewijzigd door mr_derk op 05-01-2009 22:34 ]


Acties:
  • 0 Henk 'm!

  • mocean
  • Registratie: November 2000
  • Laatst online: 04-09 10:34
Probleem lijkt mij het iframe, stel de eerste request is nog niet klaar, en er komt een 2e request, dan wordt de eerste niet afgemaakt.

In plaats van met iframe's zou ik werken met XmlHttpRequest. Je kan daarmee meerdere requests parallel uitvoeren.

Helemaal netjes is het om een soort wachtrij te maken van requests naar je server, met bijbehordende functies om te checken of de request wel uitgevoerd wordt. Zo niet, nog een keer proberen. Ook als de verbinding wegvalt kan je dan even je resultaten opsparen.

Blijft verder natuurlijk tricky, bijvoorbeeld als iemand per ongeluk de browser afsluit. Je zou eens naar Adobe Air kunnen kijken en daar je HTML/JS app in draaien. Als je de runtime daarvan download heb je binnen no-time een app met HTML/JS die aanvoelt als een applicatie ipv een website. En het voordeel dat je ook lokaal je data fatsoenlijk kan opslaan als backup.

Koop of verkoop je webshop: ecquisition.com


Acties:
  • 0 Henk 'm!

  • André
  • Registratie: Maart 2002
  • Laatst online: 23-09 13:47

André

Analytics dude

Kun je de code ergens online plaatsen en uit de topicstart halen? Is wel zo makkelijk voor de andere gebruikers :)