Autor | Zpráva | ||
---|---|---|---|
kajaman Profil |
#1 · Zasláno: 18. 3. 2010, 13:45:15
Mám stránku, na které se děje několik věcí najednou:
1, zobrazuje se aktuální cena (jedná se o aukci) 2, zobrazuje se akutální doba, která zbývá do konce aukce 3, zobrazuje se chat Všechny tyto věci jsou dotazovány přes Ajax a PHP, vytvořil jsem 3 samostatné XMLHttpRequesty, Odpočet času se akualizuje po 1 sekundě, ostatní dvě informace po 3 sekundách, abych to tolik nepřetěžoval. Nevím, jesli to nestíhá server, nebo prohlížeč, nebo připojení... Mohli byste se na to prosím kouknout a okomentovat, jestli jsem to třeba nestvořil nějak brutálně neefektivně? Moc děkuju. var httpRequest; var httpRequest2; var httpRequest2; function createXMLHTTP() { if (window.ActiveXObject) { httpRequest = new ActiveXObject("Microsoft.XMLHTTP"); httpRequest2 = new ActiveXObject("Microsoft.XMLHTTP"); } else { httpRequest = new XMLHttpRequest(); httpRequest2 = new XMLHttpRequest(); } } function createXMLHTTP2() { if (window.ActiveXObject) { httpRequest3 = new ActiveXObject("Microsoft.XMLHTTP"); } else { httpRequest3 = new XMLHttpRequest(); } } function obnov() { createXMLHTTP(); httpRequest.open("GET", "/public/akce/index/komunikator" , true); httpRequest2.open("GET", "/public/akce/index/cena" , true); httpRequest.onreadystatechange = zpracuj; httpRequest2.onreadystatechange = zpracujCenu; httpRequest.send(null); httpRequest2.send(null) } function obnovCas() { createXMLHTTP2(); httpRequest3.open("GET", "/public/akce/index/odpocet" , true); httpRequest3.onreadystatechange = zpracujOdpocet; httpRequest3.send(null) } function zpracuj() { if (httpRequest.readyState == 4) { var komunikator = document.getElementById('komunikator'); while (komunikator.childNodes.length > 0) { komunikator.removeChild(komunikator.childNodes[0]); } var vysledky = httpRequest.responseXML; var zpravy = ''; var zpravy = vysledky.getElementsByTagName('zprava'); for (var i = 0; i < zpravy.length; i++) { var item = document.createElement('li'); if ( i % 2 == 0) { item.setAttribute('class', 'barevnyRadek'); } var obsah = document.createTextNode(zpravy[i].childNodes[0].nodeValue); item.appendChild(obsah); komunikator.appendChild(item); } } } function zpracujCenu() { if (httpRequest2.readyState == 4) { var nejlepsi = document.getElementById('nejlepsi'); var vysledky = httpRequest2.responseXML; var nejlepsiCena = vysledky.getElementsByTagName('cena'); nejlepsi.innerHTML = nejlepsiCena[0].childNodes[0].nodeValue; } } function zpracujOdpocet() { if (httpRequest3.readyState == 4) { var odpocet = document.getElementById('odpocet'); var vysledky = httpRequest3.responseXML; var odpoved = vysledky.getElementsByTagName('cas'); var cas = odpoved[0].childNodes[0].nodeValue; if (cas == 'ukoncena') { odpocet.innerHTML = 'Akce byla ukončena'; } else { odpocet.innerHTML = 'Do ukončení zbývá: ' + cas; } } } obnov(); obnovCas(); $interval = window.setInterval("obnov()", 3000); $interval2 = window.setInterval("obnovCas()", 1000); |
||
Chamurappi Profil |
#2 · Zasláno: 18. 3. 2010, 14:01:42
Reaguji na kajamana:
Je to průměrně ošklivý kód. Zbytečně upovídaný, totožné úkony (třeba tvorbu XMLHttpRequest u) by měla dělat jedna funkce. Proměnnou httpRequest3 nikde nedeklaruješ, httpRequest2 deklaruješ dvakrát.
„item.setAttribute('class', 'barevnyRadek');“ Tohle nepojede v Exploreru, proč nepoužíváš vlastnost className ?
„Odpočet času se akualizuje po 1 sekundě“ Pro případ, že by čas na straně návštěvníka běžel jinak rychle, než čas na serveru? World Wide Web sice vznikl v CERNu, ale zatím na něm není nutné počítat s černou dírou či jinými časoprostorovými anomáliemi. |
||
kajaman Profil |
#3 · Zasláno: 18. 3. 2010, 14:17:05
Chamurappi:
„Pro případ, že by čas na straně návštěvníka běžel jinak rychle, než čas na serveru? World Wide Web sice vznikl v CERNu, ale zatím na něm není nutné počítat s černou dírou či jinými časoprostorovými anomáliemi.“ je důležité časování té aukce, takže se musí zobrazovat čas, který běží na serveru... |
||
kajaman Profil |
#4 · Zasláno: 18. 3. 2010, 14:26:54
Chamurappi:
„totožné úkony (třeba tvorbu XMLHttpRequestu) by měla dělat jedna funkce.“ dvě fce,protože jedna vytvoří httpRequest a httpRequest2, které potřebuji 1x za 3 vtřeřiny a ta druhá dělá httpRequest3, kterou potřebuji 1x za 1 vteřinu |
||
Chamurappi Profil |
#5 · Zasláno: 18. 3. 2010, 14:34:11
Reaguji na kajamana:
„je důležité časování té aukce, takže se musí zobrazovat čas, který běží na serveru“ Ale sekunda na straně serveru trvá stejně jako sekunda na straně klienta, takže je naprosto nesmyslné bombardovat server požadavkem každou sekundu, aby mi řekl, že uběhla sekunda. „dvě fce,protože jedna vytvoří httpRequest a httpRequest2“ Ne, na vytvoření, které provádíš třikrát stejně, stačí jedna funkce. A nepotřebuješ globální proměnné. |
||
kajaman Profil |
#6 · Zasláno: 18. 3. 2010, 14:38:24
OK, díky za kritiku.
|
||
Lopata Profil |
#7 · Zasláno: 19. 3. 2010, 20:37:36
Chamurappi:
Ale sekunda na straně serveru trvá stejně jako sekunda na straně klienta, takže je naprosto nesmyslné bombardovat server požadavkem každou sekundu, aby mi řekl, že uběhla sekunda. To není úplně pravda. Nevím, co Kajman s tím časováním tvoří, ale jestli potřebuje opravdu přesný čas, serveru se ptát musí. Javascript se totiž postupně zpožďuje |
||
Bubák Profil |
#8 · Zasláno: 19. 3. 2010, 21:16:59
Lopata:
Tak znova a pomalu. V počítači jsou hodiny s dostatečnou přesností. Javascriptový časovač použiješ jen k tomu, aby se, třeba co (přibližně) sekundu "podíval", kolik přesně uběhlo času. |
||
Lopata Profil |
#9 · Zasláno: 19. 3. 2010, 21:44:11
Bubák:
Já to samozřejmě chápu. Jen jsem zpochybnil tvrzení Chamurappiho, že sekunda na straně serveru trvá stejně jako sekunda na straně klienta, protože to nemusí být vždy pravda. V počítači jsou hodiny s dostatečnou přesností Dostatečnost je relativní. Počítáme-li z odchylkou cca 50ms za vteřinu, každou minutu se časování odchýlí o tři sekundy. Kajman si zvolil cestu AJAXu, a proto mu o přesný čas zjevně jde. A přesný čas je přesný čas, protože 60 != 63. Myslím, že bychom mu měli raději pomoci učesat ten kód, než kritizovat myšlenku jako takovou. (přibližně) Zpochybňováním přesnosti javascriptového časovače se mnou jen souhlasíš. |
||
Bubák Profil |
#10 · Zasláno: 19. 3. 2010, 22:04:56
Lopata:
„Zpochybňováním přesnosti javascriptového časovače se mnou jen souhlasíš.“ Takže naposled: Nepřesný javascriprový časovač se použije jen k tomu, aby se skript co určitou dobu "podíval" na přesné systémové hodiny. Přesnost hodin přece nezáleží na tom, jak často se na ně dívám. |
||
Chamurappi Profil |
#11 · Zasláno: 20. 3. 2010, 02:10:04
Reaguji na Lopatu:
„Jen jsem zpochybnil tvrzení Chamurappiho“ Spíš poukazuješ na vady špatného postupu, který sis sám domyslel z mého pravdivého tvrzení. „Myslím, že bychom mu měli raději pomoci učesat ten kód, než kritizovat myšlenku jako takovou.“ Za neučesaný kód si zaslouží pohlavek, za evidentně hloupou myšlenku, která při větší návštěvnosti položí server, padáka. Mimochodem, tazatelem není kolega Kajman, ale kajaman. |
||
_es Profil |
#12 · Zasláno: 20. 3. 2010, 04:55:15 · Upravil/a: _es
Lopata:
„Javascript se totiž postupně zpožďuje“ V tom článku nie je, že sa môže oneskorovať samotná hodnota času v JavaScripte, ale len spúšťanie funkcie uvedenej v SetInterval. Nejako celkom nerozumiem, o čo v tom "triku" ide. Skôr to vyzerá na to, že niekto nepochopil "problém". Užitočné by to mohlo byť, ak by ten skript mal bežať rádovo v dňoch a interval dotazovania serveru na presný čas by bol rádovo v hodinách. „Počítáme-li z odchylkou cca 50ms za vteřinu, každou minutu se časování odchýlí o tři sekundy.“ Ak sa nebude spoliehať na to, že sa časovač SetInterval spúšťa v presných intervaloch, ale radšej sa bude vždy zisťovať priamo samotná hodnota času v JS, tak to určite nemôže nastať. |
||
kajaman Profil |
#13 · Zasláno: 22. 3. 2010, 10:51:12
Jak jsem nahoře naznačil, jde o aukci, takže potřebuji pro všechny přihlášené zobrazovat serverový čas a pokud možno ve stejný okamžik - s přesností na 1 sekundu jim ukončit možnost přihodit.
Samozřejmě, že Chamurappi má pravdu, nelze „bombardovat server požadavkem každou sekundu, aby mi řekl, že uběhla sekunda.“ Pravdu mají částečně i ostatní, nelze se spolehnout na prostředí klienta. Zvolil jsem kompromis: budu v pravidelných cyklech (cca 30s) ověřovat čas na serveru a mezi tím budu odpočítávat předaný čas po sekundě. Tím snížím zátěž na server a budu mít dostatečnou přesnost odpočtu času. |
||
Chamurappi Profil |
#14 · Zasláno: 22. 3. 2010, 11:09:11 · Upravil/a: Chamurappi
Reaguji na kajamana:
„budu v pravidelných cyklech (cca 30s) ověřovat čas na serveru“ I tohle je špatný kompromis. Nemusíš se vůbec opakovaně ptát serveru. Co je na tom tak nepochopitelného? Čas skutečně běží všude stejně rychle. „mezi tím budu odpočítávat předaný čas po sekundě“ Proč odpočítávat? Proč nevyjdeš z rozdílu času u klienta? |
||
kajaman Profil |
#15 · Zasláno: 22. 3. 2010, 11:19:55 · Upravil/a: kajaman
Chamurappi:
I tohle je špatný kompromis. proč je to špatně? Synchronizaci bys neřešil? Co kdyby si někdo přenastavil v průběhu aukce systémový čas a potom řešil, že "mu to ukazovalo ještě 10 minut"... tím by diskreditoval celý systém (ačkoli by neměl samozřejmě pravdu). „Proč odpočítávat? Proč nevyjdeš z rozdílu času u klienta?“ můžu odpočítávat předaný serverový čas (resp. interval do ukončení aukce), nebo zobrazovat čas na klientově systému (resp. interval do konce aukce, který vypočtu ze systémového času a rozdílu oproti serverovému častu a času ukončení aukce). Je v tom druhém nějaká výhoda? |
||
Joker Profil |
#16 · Zasláno: 22. 3. 2010, 12:12:08
kajaman:
„Synchronizaci bys neřešil?“ Synchronizace samozřejmě nutná je, ale stačí ji udělat jednou na začátku. Já bych řekl, že pokud uběhlo třeba 5 minut systémového času na klientovi, lze s pravděpodobností nejméně 99,5% (můj odhad) čekat, že to je i 5 minut na serveru. „Co kdyby si někdo přenastavil v průběhu aukce systémový čas a potom řešil, že "mu to ukazovalo ještě 10 minut"... tím by diskreditoval celý systém“ Jak? Proč? Co by tím docílil? I kdyby byla synchronizace každou sekundu, stejně to půjde manipulovat, třeba přes Javascript zadaný do adresního řádku prohlížeče. Anebo si třeba v Opeře na stránce nechám vyhodit nějaký alert, zaškrtnu "zastavit provádění skriptů na této stránce"... a zastaví se i odpočet. Mimochodem, jestli chcete pojistku proti změně systémového času během odpočtu, stačí vyvolat novou synchronizaci v případě, že nová hodnota odpočtu se od staré liší třeba o více než 3 sekundy. Pokud se odpočet aktualizuje každou sekundu, vlivem nepřesnosti Javascriptu může nová hodnota odpočtu být o 0, 1 nebo 2s jiná než ta předchozí. Větší rozdíl by neměl nastat. „můžu odpočítávat předaný serverový čas (...), nebo zobrazovat čas na klientově systému (resp. interval do konce aukce, který vypočtu ze systémového času a rozdílu oproti serverovému častu a času ukončení aukce). Je v tom druhém nějaká výhoda?“ Ano. Jelikož to načasování Javascriptem není úplně přesné (samotný časovač má alespoň tak 20-30 milisekund rozptyl a provádění té funkce taky nějakou dobu trvá), první způsob se bude postupně vzdalovat od skutečnosti. Podle mých zkušeností to vyrobí rozdíl několik sekund každou minutu. Naopak ten druhý způsob (na začátku stanovit rozdíl mezi klientem a serverem a pak počítat podle klienta) bude (v rámci nějakých rozumných hranic) přesný. |
||
kajaman Profil |
#17 · Zasláno: 22. 3. 2010, 12:14:52
Joker:
děkuji, promyslím to. |
||
_es Profil |
#18 · Zasláno: 22. 3. 2010, 12:15:24
kajaman:
„Co kdyby si někdo přenastavil v průběhu aukce systémový čas a potom řešil, že "mu to ukazovalo ještě 10 minut"... tím by diskreditoval celý systém“ To treba správne definovať pravidlá, ak bude určené, že aukcia bude ukončená v nejaký presný UTC čas, tak to odpočítavanie bude len pomocné a návštevník si bude sám na vine, že má zle nastavený systémový čas alebo si ho počas aukcie prenastavil. To zlé nastavenie sa dá riešiť tým rozdielom, ako ti radil Chamurappi. |
||
Chamurappi Profil |
#19 · Zasláno: 22. 3. 2010, 12:29:05
Vlezl mi do psaní odpovědi poměrně dobrý oběd, takže budu asi trochu redundantní, ale mazat se mi to nechce :-)
Reaguji na kajamana: „Synchronizaci bys neřešil?“ Ne. „Co kdyby si někdo přenastavil v průběhu aukce systémový čas a potom řešil, že "mu to ukazovalo ještě 10 minut"“ Předpokládám, že čas odměřovaný na straně klienta nemá dopad na funkčnost na straně serveru. Takže když si na své straně s něčím úmyslně hne (ať už jde o změnu systémového času, nebo o spuštění bookmarkletu přepisujícího nějakou tvoji proměnnou), nemůže si nárokovat stoprocentní funkčnost. Kromě odpočtu budeš asi někde ukazovat i skutečný čas konce aukce, ne? Takže ten odpočet stejně bude jen orientační. „Je v tom druhém nějaká výhoda?“ Lepší přesnost (respektive nepřesnost neměnná v čase), menší nároky na připojení i na zátěž serveru. |
||
Časová prodleva: 14 let
|
0