JavaScript: aszinkron adatlekérés

3. Aszinkron hívások

Az erőgyűjtés utolsó részében arról lesz szó, hogy miképpen lehet Javascript segítségével távoli szerverektől adatot lekérni az oldal újratöltése nélkül.

1

AJAX bevezetés

A modern honlapok esetében nem lehet mindent statikus oldalakkal megoldani, ahogy az sem várható el, hogy minden információt a szerver határozzon meg. Az eddigiekben, bár az oldal tartalmát Javascript segítségével tudtuk változtatni, a tényleges adatok mindig ugyanazok voltak. Manapság egyre gyakoribb viszont, hogy a weboldal csak kevés információ birtokában töltödik be, és ha új adat kezelésére van szükség, azt a szervertől utólag kéri le. Itt jönnek a képbe az XML HTTP lekérések és az AJAX.

A távoli lekérés lényege, hogy a Javascript kód egy XMLHttpRequest-et küld a szervernek, amire az válaszol, jellemzően szöveges formátumban. Ez lehet egy egyszerű szöveg is, de mivel jellemzően strukturált adatok lekérésére használjuk, ezért a formátum is ennek megfelelő, tipikusan XML, vagy újabban JSON. Mi most az XML-es verziónál maradunk. A következő kódrészlet bemutatja egy alapvető XMLHttpRequest küldését és a válasz fogadását:

A kódrészletet egy függvénybe foglaltuk, hogy tetszés szerint meghívhassuk. Először létre kell hozni a kérést kezelő objektumot. Az open függvény segítségével megadhatjuk a kapcsolat adatait, mint a cél (jelen esetben egy, az azonos szerveren található ajax_info.txt fájl), illetve az adatküldés típusa (GET vagy POST, mint a form-ok esetében is). A harmadik paraméter igazra van állítva, hogy a hívás aszinkron legyen, és közben a weboldal működése ne fagyjon le. A send() hatására a kérést elküldjük. Már csak a második utasítás maradt ki. Egy ilyen kérés megvalósítása több lépéses, és ezen a ponton egy függvényt rendelünk a kérés állapotának figyeléséhez. Most csak a legvége érdekel minket, de minden állapotváltozásra reagálhatunk ezzel, ha szeretnénk. Ellenőrizzük, hogy a kérés állapota az legyen hogy megjött a válasz (ez a 4-es kód), valamint hogy sikeres legyen a kérés (amit a 200-as status kód jelöl). Ilyenkor tudunk a sikeresen visszakapott válasszal dolgozni, amit a példakód egyszerűen kiír az oldalra.

Ezzel az egésszel a probléma a gyakorlatban lesz, hiszen az ilyen webldalak mögött általában áll egy webszerver is, amelyiktől le tudják kérni az adatokat. Esetünkben viszont ilyen szerver nem áll rendelkezésre. Szerencsére az interneten elég sok szervert lehet találni, amitől távoli kérésekkel adat szerezhető, így ezekre fogunk a későbbiekben támaszkodni.

Nézzünk is egy tényleges példát. Célpontnak szinte bármit meg lehet adni, azonban mivel a mi kódunk mögött nincs egy szerver, és nem a saját szerverünktől kérünk adatot, korlátokba ütközhetünk. Az olyan kéréseket, amikor másik szerverhez intézünk távoli kérést, Cross-Origin Resource Sharing-nek nevezik, és a probléma az, hogy sok szerver nem engedélyezi ezeket. Erre szerencsére lehet megoldást találni, és az egyik legegyszerűbb az, ha egy proxi-ként üzemelő köztes szervert használunk. Ilyen például a CORS Anywhere szerver, ahogy a lentebbi példakódban is látható. Egyszerűen a megadott cím után kell fűzni az általunk lekérni kívánt címet, és meg tudjuk kerülni a problémát.

Bizonyos szervereket úgy állítanak be, hogy engedélyezik a máshonnan érkező távoli kéréseket. Ilyen szerver az is, amit majd a feladat megoldásához kell elérni. Nézzünk erre is egy példát, ahol nem kellenek ezek a trükkök. Ez a példa egyúttal mást is megmutat: a JSON (leírás, tutorial) alapú kommunikációt. A szerverhez az adatokat ezúttal POST segítségével továbbítjuk. Ezen felül a send kap egy paramétert, amit továbbküld. Ez a paraméter egy szabványszerű JSON szöveg. Az adatot objektum formájában írjuk le, majd JSON szöveggé alakítjuk. A szerver ezt elemezve fogja tudni, hogy mi a pontos kérés.

« Előző | Lap eleje

2

Canvas kezelése

A feladat megoldásághoz szükség lesz grafikai megjelenítésre, amire jó opciót ad a HTML-ben található Canvas. Linkek:
Link
Link

A Canvas használatához az szükséges, hogy az oldalon legyen egy ilyen típusú elem, amit JavaScript segítségével el tudunk érni, majd hozzá kell férni ezen az elemen belül a rajzolási környezethez (context). A rajzolást magát azt innentől vonalak és ívek rajzolásával lehet megoldani. Fontos, hogy a canvas számára a 0,0 pozíció a bal felső sarokban van, az x koordináta jobbra, az y pedig lefelé növekszik. Az ismételt rajzolást úgy oldhatjuk meg, ha beállítunk egy ismétlődő időzítőt, ami bizonyos időközönként meghívja a rajzoló függvényt. Ilyen esetben célszerű a canvas tartalmát a rajzolás előtt törölni is. Egyéb fontos információ, hogy a Canvas a szövegeket radiánban méri, ahol a 0 fok jobbra van, a 90 fok (radiánban PI/2) pedig lefelé: Canvas arc().

« Előző | Lap eleje

3

Oldd meg a feladatokat!

Kedves Bakonyi Bitfaragó Jelöltek!

Ez a rész bevezetést adott a távoli lekérésekhez, valamint a Canvas használatához. A beadandó feladat ezen információk használata a Bitközpont szerverrel való kommunikációra. A feladat során egy szoba mozgásérzékelő szenzorainak adataival kell dolgozni.

A szoba alapja egy 500cm x 500cm-es négyzet, amelyben 4 db, egyenként 400cm hatósugarú mozgásérzékelő helyezkedik el. A mozgásérzékelők egy-egy adott irányba néznek, és 90 fokos látószöggel rendelkeznek (ha 40 fokos irányba néz, akkor -5 foktól 85 fokig lát). A mozgásérzékelők pozíciói és irányaik (a Canvas koordinátarendszerében 1 egység 1 cm, és a szögek is ezen rendszernek megfelelőek):

  1. X: 0, Y: 150, Szög: 40 fok
  2. X: 150, Y: 500, Szög: 310 fok
  3. X: 500, Y: 350, Szög: 220 fok
  4. X: 350, Y: 0, Szög: 130 fok
A feladatban minden szöget fokban ad meg, de fontos megjegyezni hogy a számítások során radiánnal szokás dolgozni (a függvények is ezt várják). A szenzorok kirajzolására egy egyszerű példa:

A szerverhez a következő címen kell kérést intézni: http://bitkozpont.mik.uni-pannon.hu/Vigyazz3SensorData.php. A kérésbeli adatokat POST segítségével, JSON formátumban kell elküldeni, és a válasz is így érkezik. A szerverhez intézhető kérések:

Példaképp a lentebbi

A szenzorok általi érzékelés részletezése:

A szenzor az érzékelés során azt számolja ki, hogy a saját irányához képest (a látómezőjének a közepe) milyen irányban érzékel. Tehát ha a szenzor a 40 fokos irány felé néz, és a 27-es irányban érzékel (relatív, magához képest), akkor valójában (abszolút rendszerben) a szenzorhoz képest a 40+27=67 fokos irányban van, amit érzékelt. A visszaadott válasz így mindig -45 fok és 45 fok között lesz (hiszen ez a szenzor látómezeje). A szenzorok érzékelése némiképp pontatlan, a ténylegesen helyes adattól legfeljebb 2 fokkal eltérhet a mért érték (ez azt is jelenti, hogy a látómező szélén néha nem vesz észre valakit). Egy példa látható a lentebbi ábrán. A szenzor a 40 fokos irányba néz. Valaki (piros pötty) megmozdul tőle 9 fokos irányba (abszolút irány). Ez azt jelenti, hogy a szenzor relatív rendszerében ezt az irányt 9-40=-31 fokként kellene érzékelnie. Azonban a szenzor pontatlan, így a ténylegesen érzékelt érték -32.5 fok körüli (2 fokos eltérésen belül van a tényleges értékhez, de véletlenszerű a hiba). A halvány piros sáv azt jelöli, hogy ha a szenzor által adott érzékelés -32.5 fok, akkor a 2 fokos eltérést számítva hol lehet a tényleges mozgás.

Beküldhető feladatok:

  1. A feladat részletezése a következő:
    • A szervertől lehessen lekérdezni a szenzorok pozícióit és irányait, ami valahol jelenjen meg.100|2 pont
    • Az oldal jelenítsen meg egy 500x500-as canvas-t, amire rajzolja fel 4 szenzort. A szenzorokon látszódjon hogy merre néznek.1000|2 pont
    • Legyen egy opció, amit bekapcsolva megjelennek a szenzorok látómezői is (-45 és 45 fok között eltérés, max 400 távolság).100|2 pont
    • Legyen a pályán egy személy, ami mozgatható valamilyen módon (billentyűzet, egér segítségével).1 0000|2 pont
        A mozgatás módjához és lehetőségeihez legyen egy segédlet.
    • A mozgatás során a kliens kérdezze le a szervertől, hogy a szenzorok mit érzékelnek az adott pozícióra (version 1).100 0000|2 pont
        Ilyen lekérés másodpercenként max 30 legyen, így is lehet hogy néhány válasz későn érkezik meg.
        A szerver által adott válasz alapján minden szenzorhoz (ami érzékelt valamit) rajzoljátok ki a legfeljebb 2 fok eltéréshez tartozó hibasávot (a szenzor közepéből a látótávolságig).
        Egy nagyon fapados példa megjelenítés:
          
    • Legyen olyan opció, hogy a szervertől lekérjük a méréseket ismeretlen pozícióra (version 2).10 0000|2 pont
        A hibasávok itt is jelenlenek meg.
    • Amikor a szervertől megkapja az oldal a szenzorok méréseit, tipplje meg a mért objektum pozícióját.100 0000|2 pont
        A tippelés csak akkor megy, ha legalább két szenzor érzékelte a mozgást.
        A pályát osszátok fel 5x5 részre (100x100-as négyzetek).
        A tippelésnél csak annyit kell mondani, hogy az így kapott 25 négyzet közül melyikben lehet a mozgás forrása.
        A megoldásnak az ismeretlen pozíciós verzió esetén is működnie kell.

    Összesen 1100 0000|2 pont

« Előző | Lap eleje

Hivatkozások, felhasznált források

[1] Mozilla developer network: DOM

[2] CSS alapjai I.

[3] AJAX leírás

[4] Canvas leírás