Node.js alapok
A Node.js (vagy másnéven Node) egy rendszer, melyben JavaScriptben írhatunk szerver oldali alkalmazásokat. Maga a rendszer C/C++-ban íródott, és egy esemény alapú I/O rendszert takar a Google V8 JavaScript motorja felett.
Célok
A sorozatban megjelent
- Node.js alapok
- Node.js alapok II.
A Node célja, hogy egy egyszerű felületet adjon, arra, hogy skálázható hálózati alkalmazások írására. Azt tudjuk, hogy a JavaScript a világon a jelenleg legnépszerűbb programozási nyelv, többek között ezért esett erre a nyelvre a választás. A JavaScript nyelvnek vannak más sajátosságai, amelyek szintén előtérbe kerülnek a rendszer használata során. Ahogy a böngészőben, úgy Node alatt is egyetlen esemény hurokban (event loop) fut a program, és ez adja az egyik legfontosabb előnyt.
A Node.js-t úgy írták meg, hogy (szinte) minden esemény aszonkron legyen, ezért az program sosem blokkolódik, azaz nem kell várni, hogy egy művelet befejeződjön, vele párhuzamosan futtathatunk további műveleteket. Ez pontosan ugyan úgy működik, mint a böngészőben levő XHR kérések, vagy más események, mint például a click, mouseover. Ez az alkalmazás folyamatosabb futását, több alkalmazás párhuzamosítását, valamint az egész rendszer optimálisabb működését teszi lehetővé.
Telepítés
Szinte akár milyen operációs rendszerre telepíthetjük a Node-ot, Linuxtól kezdve a Mac OS X-en át a Solarisra. Fordíthatjuk ezen kívül Windows alatt Cygwin-en, FreeBSD-re és OpenBSD-re. A rendszer telepítése elég egyszerű, letöltjük az aktuális stabil változatot, konfiguráljuk, és fordítjuk (make
). A fordításhoz szükségünk van egy C++ (gcc) fordítóra, és a Python 2.4 vagy újabb változatára.
$ mkdir node-latest-install $ cd node-latest-install $ curl http://nodejs.org/dist/node-latest.tar.gz | tar xz --strip-components=1 $ ./configure $ make install
Ez lefordítja a Node.js-t valamint a benne található V8-as motort is, azaz azt nem kell külön letölteni és telepíteni. Ezen írás idején a Node stabil változata a 0.2.4 ami a V8 2.3.8 változatával érkezik. A jelenleg fejlesztés alatt levő változat a 0.3.0.
Ismerkedés
Amennyiben a telepítés sikeresen lezajlott, mentsük el a következő JavaScript alkalmazást hello.js néven:
console.log('Hello');
setTimeout(function () {
console.log('World!');
}, 2000)
Majd futtassuk a következőképpen:
$ node hello.js
Ekkor előbb a konzolon megjelenik, hogy Hello, majd 2 másodperccel később, hogy World!.
Az egyik lényeges különbség például a PHP-hoz képest – azon kívül, hogy JavaScript-ben írjuk az alkalmazásunkat –, hogy nincsen szükségünk HTTP szerverre (mint amilyen az Apache httpd), mivel mi magunk írjuk a HTTP szerverünket. Írjuk is meg az első hasonló alkalmazásunkat httpszerver.js néven:
var http = require('http');
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World\n');
}).listen(8124);
console.log('Server running at http://127.0.0.1:8124/');
A következő módon tudjuk futtatni:
$ node httpszerver.js
Ekkor a programunk a 8124-es porton várakozik a HTTP kérésekre, és csak annyit ír ki a böngészőben a http://127.0.0.1:8124/ URL-re látogatva, hogy Hello World.
Modulok
A Node.js alapértelmezetten is rengeteg modullal érkezik, hasonlóan az előbb említett http modulhoz. A modulok a CommonJS specifikáció szerint íródtak, és ennek megfelelően a require('modulneve');
paranccsal tudjuk behúzni őket az alkalmazásunkba. Ezek egy objektumot tesznek elérhetővé, és egy változóhoz rendelve később kényelmesen tudjuk használni is őket. Az alap telepítésben elérhető modulokról a Node hivatalos API dokumentációjában olvashatunk.
npm
A Node hivatalos csomagkezelője az npm, amellyel kényelmesen listázhatjuk, telepíthetjük, frissíthetjük és eltávolíthatjuk az elérhető modulokat, valamint mi magunk is publikálhatjuk az általunk fejlesztett modulokat az npm rendszerébe. Rendszerkövetelményei azonosak a Node-éval, telepítése egyszerű:
$ curl http://npmjs.org/install.sh | sh
Jelenleg több mint 600 modul érhető el az npm rendszerében. Természetesen a modulok minősége változó, de azért könnyű találni a konkrét problémát megoldó modulok közül a nekünk megfelelőt.
Az elérhető modulok listáját az npm ls paranccsal érhetjük el, és ezek nevében a split()
parancsnak megfelelő paramétert átadva szűrhetünk is, tehát reguláris kifejezéseket is használhatunk. Például:
$ npm ls xml
Ez szűri azon modulokat, melyek nevében az „xml” szerepel.
Amennyiben további részletekre vagyunk kíváncsiak egy modullal kapcsolatban használhatjuk a view
parancsot, mely egy JSON objektumban írja le a modult, például nevét, leírását, szerzőjét, a repository-t, ahol elérhető a forráskód, a modul weboldalát stb.
A modulokat az install
paranccsal telepíthetjük.
$ npm install underscore
A frissítésre az update
eltávolításra az uninstall
parancs szolgál. További segítséghez használjuk a help
utasítást.
Példa alkalmazás
Írtam egy kicsit összetettebb alkalmazást a jQuery API dokumentáció helyi szintű tükrözéséhez és megjelentéséhez. Ehhez a következő modulokra van szükségünk: EJS, Express, Underscore és Connect. Ezeket egyszerűen telepíthetjük:
$ npm install underscore ejs connect express
Az EJS egy JavaScript template keretrendszer, ezt használjuk majd a megjelenítéshez. Az Underscore egy funkcionális programozást segítő függvénytár. A Connect egy összetett keretrendszer, amely többek között HTTP kéréseket, routingot, GET/POST/süti feldolgozást, statikus fájlok kiszolgálását segíti. Az Express pedig a Connect-re épülő Sinatra-ra hasonlító fejlesztői keretrendszer.
Építsük fel az alkamlazásunk gerincét tartalmazó app.js fájlt.
var express = require('express'),
http = require('http'),
underscore = require('underscore')._,
apiURL = 'api.jquery.com',
app = express.createServer(express.logger()),
apiClient = http.createClient(80, apiURL),
apiRequest = apiClient.request('GET', '/jsonp/', {'host': apiURL}), // Indítunk egy kérést az API oldalhoz
database = [],
paths = [];
// Segédfüggvény reguláris kifejezések escapelésére.
underscore.escapeRegex = function (text) {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
}
app.dynamicHelpers({
basepath: function(){
// "this" is the app, we can
// dynamically provide the "home"
// setting to all views
return this.set('home');
}
});
// Az alkalmazásunk "ejs"-t használ renderelésre.
app.set('view engine', 'ejs');
// Kezeljük az API kérést.
apiRequest.on('response', function (response) {
var data = '';
response.setEncoding('utf8');
// Várjuk, hogy érkezzen adat
response.on('data', function (chunk) {
// Megjött az adat
if (!data) {
// Az első csomagból levesszük az első karaktert, az nem fog kelleni, mivel a válasz JSONP
chunk = chunk.substring(1);
}
data += chunk;
});
response.on('end', function () {
var rePath = new RegExp('^(?:https?:\\/\\/)?' + underscore.escapeRegex(apiURL) + '\\/(.*?)\\/?');
// Levesszük az utolsó karatert is, mivel az is a JSONP része.
data = data.substring(0, data.length - 1);
// Jelezzük, hogy megjött az összes adat.
console.log('RESPONSE END');
// Feldolgozzuk az adatot az 'adatbázisunkba' (JS Ojbektum).
database = JSON.parse(data);
// Kicsit átszervezzük az adatokat.
underscore.map(database, function (value, index) {
value.path = value.url.replace(rePath, '$1').replace(/\./, '_');
value.desc = value.desc.replace(/\/Selectors\/(\w+)/g, '$1-selector');
paths[index] = value.path;
return value;
});
});
});
// Ténylegesen el is küldjük a kérést.
apiRequest.end();
// Kezeljük a kérést ami a `/`-re érkezik
app.get('/', function (request, response) {
var i = 0,
item,
basepath = app.set('home'),
output = '';
// Kilistázzuk az összes elérhető függvényt.
response.render('index', {locals: { entries : database }});
});
// Kezelük a kérést, ami egyetlen jQuery függvényre vonatkozik
app.get('/:method', function (request, response) {
var method = request.params.method, // Ebben lesz a függvény neve.
index = underscore.indexOf(paths, method); // Megkeressük az adatbázisban
entry = index !== -1 && database[index]; // Megvan az elem?
if (entry) {
// Megvan az elemünk, írjuk ki a leírását.
response.render('entry', {locals: { entry: entry }});
}
else {
// Nincs meg a függvény.
response.send(method + ' does not exist', 404);
}
});
// A 3000-es porton figyelünk HTTP csatlakozásokat.
app.listen(3000);
console.log('Server running at http://127.0.0.1:3000/');
Az alkalmazáshoz kapcsolódó template fájlokat helyezzük a views almappába. Három ilyen template állományt használunk.
A HTML keretért felelős views/layout.ejs:
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>jQuery API - Node.js application by Poetro</title>
</head>
<body>
<h1>jQuery API - Node.js application by Poetro</h1>
<%- body %>
</body>
</html>
Az index oldalunkon megjelenítendő listázást végző views/index.ejs:
<h2>Available functions:</h2>
<dl>
<% for (var i = 0; i < entries.length; i++) { %>
<dt><a href="<%= entries[i].path %>"><%= entries[i].title %></a></dt>
<dd><%- entries[i].desc %></dd>
<% } %>
</dl>
Valamint az egyes elemek megjelenítését végrehajtó views/entry.ejs:
<h2><%= entry.title %></h2>
<dl>
<dt>Proof that it is generated</dt>
<dd><%= Math.floor(Math.random() * 9e8) + 1e8 %></dd>
<dt>Description</dt>
<dd><%- entry.desc %></dd>
<dt>Type</dt>
<dd><%= entry.type %></dd>
<dt>Original entry</dt>
<dd><a href="<%= entry.url %>"><%= entry.title %></a></dd>
<dt>Returns</dt>
<dd><%= entry.return %></dd>
</dl>
<div id="description">
<%- entry.longdesc %>
</div>
Böngészőnkben a http://localhost:3000/ URL-re látogatva a következőhöz hasonló oldal fogad majd minket, amennyiben mindent jól csináltunk:
jQuery API index oldal
Ha innen az egyik függvény nevére kattunk, akkor a következőhöz hasonló oldalra jutunk:
jQuery API add()
függvény
Zárszó
Amint látszik, egy még igencsak friss kezdeményezésről van szó, ugyanakkor már most rengeteg fejlesztő, és ennek megfelelően sok elérhető fejlesztés van a projekt mögött. Amennyiben mutatkozik igény egy cikksorozatra, akkor részletesebben bemutatom a lehetőségeket, pár igencsak használható modult, és hogy mire érdemes, és milyen hatékonysággal lehet használni a Node.js-t.
■
Jó cikk lett! Már én is
Releváns előadások
Releváns lehet az előadásom a témáról:
http://www.slideshare.net/ba78/nodejs-3602172
nagyon könnyen lehet olyan
Többszörös forgalom
Talán ha érteném. :( Például,
Példa
Úgy értsem, hogy LAMP vs.
LNMP?
Nem, csak támpont nélkül
Mivel eredetileg LAMP-pal kapcsolatban kérdeztem és te összehasonlítással válaszoltál, úgyhogy megpróbáltam felállítani az egyenlőtlenséget: egyik oldalon L+A+M+P, másik oldalon gondolom valami hasonló, csak a négy alkotó közül az egyik Node.js lesz. Az LNMP kérdésem erre vonatkozott: hol jön a képletbe a Node.js.
Az összehasonlítást (és persze a cikket) köszönöm, de egyelőre nem állt össze a kép. Úgyhogy én is várom a téma következő cikkét.
LAMP / LNMP
Most már világos a felállás,
Hasznos cikk volt, köszönjük!
Nem hallottam még erről, de kifejezetten elkezdett most foglalkoztatni.
Adatbázis kapcsolatok terén hogy áll a node?
Adatbázisok
Azt kell, hogy mondjam, hogy elég jól, főleg a NoSQL adatbázisok terén, de természetesen létezik már MySQL és PostgreSQL csatoló is.
Tetszik ez a node.js,
Nekem van igényem ilyen cikkekre, érdekesek.
php elasni, js-t isteniteni ?
1: miota nem lehet parancssorbol futattni phpt?
2: miert ne lehetne php-ban irni http servert ?
Lehet hogy nekem kopott meg a tudasom az elmult evekbe, de az is lehet hogy a cikk irojanak nincs tapasztalata php-val.
alapvetoen a tema erdekes, varom a kovetkezo reszt...
nem
És elárulom, van tapasztalatom PHP-val, az utóbbi 10 évben igencsak sokat foglalkoztam PHP-val, bár lehet más szemszögből vizsgáltam a PHP-t mint amire gondolsz. És tudom, és szoktam használni a PHP-t parancssorban, de nem ez a leggyakoribb használata. Felteszem, lehet HTTP szervert írni PHP-ban is, de nem hiszem, hogy teljesítményben fel tudná venni a versenyt akár csak az Apache httpd-del, vagy a Node.js-sel.
hát a cikk alapján komolyan
nagyon nagyon hasznos cikk. még még :)
hát a cikk alapján komolyan
Én nem ítélnék ennyire elhamarkodottan, még simán kinőheti ezt a 10x-es különbséget is, ha teleszórják szeméttel. :-)
Node.js v0.2.5 és v0.3.1
azért azt ne felejtsük el
production ready
node.js fejlesztés
A 2010es js confon meg 9 challeng-ről beszélt ami a node.js előtt áll fejlesztésben. Azóta furcsa mód már megváltozott annak a pdf-nek a tartalma. :) Lehet hogy olyan gyorsan fejlődik a kód hogy akár már élesbe is lehet tenni. Bátraké a szerencse.
Ez csodás
Ezek szerint lehetséges akár, Windows alatt futtatható asztali alkalmazásokat is írni JS-ben? Ha, igen hogyan? Ehhez milyen keretrendszer, fejlesztői környezet kell?
JScript.NET
.exe
-re.Biztonság?
Köszi a cikket, engem érdekel a folytatás!
Tudnál esetleg pár szót írni a node.js biztonsági paramétereiről?
Mire gondolsz?
node.js npm install gond
Tud valaki abban segíteni, hogy miért nem lehet az npm-et felinstallálni?
Ezt az üzenetet kapom:
$ node ./cli.js install npm
npm info it worked if it ends with ok
npm info using npm##kukac##0.2.12-1
npm info using node##kukac##v0.2.4
npm ERR! Error connecting to server http://registry.npmjs.org/npm
npm ERR! Error: ETIMEOUT, Timeout while contacting DNS servers
npm ERR! at Timer.callback (dns:15:13)
npm ERR! at node.js:772:9
npm ERR! Report this *entire* log at <http://github.com/isaacs/npm/issues>
npm ERR! or email it to <npm-##kukac##googlegroups.com>
npm ERR! Just tweeting a tiny part of the error will not be helpful.
npm not ok
Előre is köszönöm, ha valakinek van ötlete!
Tűzfal
Re: tűzfal
Megpróbáltam az általad leírt módon is telepíteni ( bár ennek a vége ugyanaz a szkript, ami elakad ), de értelemszerűen ez is leállt azon a bizonyos ponton.
A node.js telepítése sikerült, ez az npm, ami kifogott rajtam :)
cygwin
A probléma megoldva
A megoldás kulcsa:
az/etc/resolv.conf-ban ezt a két sort el kell még helyezni:
nameserver 8.8.8.8
nameserver 8.8.4.4
Enélkül nem működik, de ezek után minden rendben :)