Tapasztalatok: Node.js, Jaxer, ExpressJS, MongoDB, Github

 ( andrasf | 2010. május 27., csütörtök - 15:45 )

Mivel készül a saját hobbiszerverünk, mostanában értelmes tevékenység helyett perverz webkiszolgálási lehetőségek után kutatok. PHP+MySQL alapon hozzáférek több kiszolgálóhoz is, ezért a saját szeveremre szeretnék valami mást. Nézegettem a Ruby on Rails-t, de nem tetszik nekem a Ruby szintaxisa. Nagyon szeretem viszont a Javascriptet, főleg mióta komolyan megtanították nekem az elméleti alapjait. Nagyon-nagyon dinamikus, prototípus alapú, és jó esetben még gyors is.

Először az Aptana Jaxert néztem meg, ez nagyon tetszett. Minden sokkal szerveroldalabbi kontrol, mint az ASP.NET-nél, könnyű volt telepíteni, bármilyen JS-t lehet használni vele szerveroldalon is (akár jQuery-t is pl.). Ezt a <script runat="client|server|both"> opció dönti el.

Tehát például nem a while ciklusban kell eldönteni (mint php-nál) hogy echozom-e a táblázat páratlan soraihoz hogy más színűek legyenek mint a páros sorok, hanem ha kész a táblázat akkor egyszerűen $("#tablazat tr:odd td").css("background", "más szín"), mindezt szerveroldalon. Ha írok egy függvényt ami mondjuk adatbázissal kommunikál (mysql-lel a letöltéstől számítva nagyon hamar és problémamentesen sikerült kommunikálnom egyébként), akkor az vagy <script runat="server-proxy"> segítségével, vagy

<script runat="server">
    function fuggveny(){}
    fuggveny.proxy=true;
</script>

segítségével lehet elérhetővé tenni kliensoldalról, ilyenkor egy erre irányuló kérés AJAX kérésként fog végbe menni. Szerintem ez nagyon jó ötlet, sajnos azonban az érdeklődés hiánya miatt a Jaxer lassan hivatalosan is halott. Úgy gondolom, hogy ennek az az oka, hogy végülis arra lehet használni mint a PHP-t, és a JS előnyeiből semmi különöset nem sorakoztatott föl.

Nem halott viszont a node.js, ami a V8 motorral működik. Alacsonyabb szintű szervereket lehet vele írni alapvetően, akár egy socketen is figyelhet, akár tcp-n, vagy http-n. A kapcsolatot nem csukja be magától, így comethez és long-pollinghoz ideális. A node.js lényege az, hogy sosem szeretne várni az I/O-ra. Ez azt jelenti, hogy a javascriptben megszokott callback függvényekkel operál, és például egy feltöltődő fájl minden darabkájának megkapásakor egy eseménykibocsátó (event emitter) kibocsát egy eseményt, amihez mi egy eseményfigyelőt rendelhetünk, és ehhez egy anonim függvényt adunk át. Így nem indul minden kiszolgáláshoz új szál, hanem egy szálon történik minden. Egy elképzelt (egyszerű) adatbázisos kód tehát így nézne ki: db.query("select * from x full outer join y", function(cursor) { for(var i in cursor) sys.puts(cursor[i]);} ); Itt ugye az a lényeg, hogy ha van több tevékenység is, akkor a kód nem fog rögtön arra várni hogy lefusson a lekérdezés, hanem foglalkozik addig mással. Van amikor az eseményt konkrétan is jelezni kell (tehát rendes eseményfigyelőt rendelünk az eseményhez), például:

db.addListener("close", function () {
    sys.puts("Becsukódtam.");	
});

db.addListener("connect", function () {
    sys.puts("Megnyitódtam.");
    db.close();
});

db.connect({
    hostname: '127.0.0.1',
    port: 27017,
    db: 'adatbazis'
});

Egy másik érdekes dolog a mongodb, ami egy dokumentum orientált adatbázis. JSON jellegű adatokat lehet benne tárolni, amiket collection-ökbe szervez. Például: db.emberek.save({nev: "András", kedvenc_szinek: ["fekete","kék", "zöld"], valami: {barmi: "hatvan", akarmi: 60}}); módon tárolhatunk benne adatokat. Utána: db.emberek.find(); vagy db.emberek.find({nev: "András"}); esetleg db.emberek.find({_id: {"$lt": 2000} });, stb.

Interaktívan kipróbálni erre tessék :)

A mysql elérés egyébként nem ment nekem node.js-sel, ezen kívül elhiszem hogy mindent aszinkronná tenni nem túl egyszerű. (Mivel egy fájl elérése alapból blokkol, ezért mindenféle trükkök jönnek képbe. Ilyen esetekben egyébként amennyire néztem van szinkron és aszinkron változat is).

A node.js-hez van olyan hogy expressjs, amit ha jól emlékszem a sinatra-hoz hasonlítottak. Ezzel az MVC frameworkökből ismerős módon lehet adatokat passzolni a nézetnek (illetve tulajdonképpen pont az), és kicsit template rendszer is, valamint partial view-t is tud renderelni. Az ASP.NET MVC2 után teljesen ismerős volt az egész. Mondjuk a haml nekem idegen, maradok az ejs-nél. Könnyű vele szép url-eket csinálni, pl. get('/cim/:valtozo/barmi', function(valtozo)... esetben a /cim/valtozo/barmi címet érték el, amiből mi a valtozo értékét valamire fel szeretnénk használni (pl. cikk vagy termék azonosítója). Ugyanígy létezik persze a post('/cim/:valtozo/barmi' , function(valtozo)... is, ilyenkor a post adatokat a this.param("valtozo_neve") függvénnyel érjük el. Ezek lehetnek a php-ból megszokott módon tömbök is.

A node.js-hez két mongodb modul is van (1, 2), a másodikban gond volt az UTF-8 kódolással. Nyitottam egy issuet, leírtam hogy mi a bajom, a szerző azt válaszolta hogy forkoljam és írjak az integration_tests.js-be egy test case-t, aztán küldjek neki egy pull requestet. A pull requestet nem sikerült elküldenem, meg a gittel is szenvedtem egy kicsit, de 12 órán belül fixed lett az issue. Na. Ez a valami! :) (Egyébként hogyan kell pull requestet küldeni?)

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Github:
A forkolt repod főoldalán, a neved/repo_neve címmel egy sorban van egy menüsör, 3. eleme a Pull Request.

[(meglepetés) azzal lehet pull requestet küldeni : )]

Ah, tényleg. Kösz :)

A legfontosabb kerdes szamomra: es hogyan teljesitenek, mennyire gyors igy a kiszolgalas?

---
return NEVER;

Ubuntu 8.10
HP nx6110
http://java.tszebeni.hu

A node.js-t elvi szinten az nginx-hez hasonlítja a szerzője (az apache-val szemben), itt vannak benchmarkok.

Apache vs nginx benchmarkok pedig itt vannak.

latom terjed a javascript pestis.
egyetlen tulajdonsagot mondjon mar valaki, amiben jobb a java-nal.
az, hogy a java ala kell vm, az nem er.

látom értesz hozzá :)

Teljesen más a kettő. A java pestis is nagyon el van ám terjedve :)

Egyébként pl. webes területen a JSON (alapból a formája és a dinamikus mivolta), a névtelen függvények (főleg callbackhez) nagyon jók. Nekem személyesen tetszik a gyenge típusossága és a prototípus alapúsága is. Nagyon dinamikus, bármikor bármihez (vagy bárminek a prototípusához) hozzátehetsz bármit. Hogy ezeket (gyenge típusosság, prototípus) előnynek vagy hátránynak vesszük, az attól is függ hogy mire akarjuk használni, és attól is hogy ki mit szeret.

Engem az érdekelne, hogy miért kell a java-hoz olyan sok xml fájl, meg ant script. Brr. Meg hogy a JSF miért áll olyan sok fájlból, és miért nem gondolták olyan fontosnak a GET változókat.

Szerintem ebben a hozzászólásodban benne volt minden. :)

-----
"Egy jó kapcsolatban a társunkat az ő dolgában kell támogatni, nem a miénkben."

Mármint?

Nem neked válaszoltam. :)

-----
"Egy jó kapcsolatban a társunkat az ő dolgában kell támogatni, nem a miénkben."

Tudom, én viszont téged kérdeztelek. :)

Javascript != Java, oviban tanítják.

-----
"Egy jó kapcsolatban a társunkat az ő dolgában kell támogatni, nem a miénkben."

Reméltem hogy így kell érteni :)