Návod k použití Node.js na FI
Běhové prostředí Node.js slouží k vytváření programů
v jazyce JavaScript. Tato platforma je primárně určena pro běh
samostatných serverů poslouchajících na dedikovaném TCP portu, což platí
i pro webové frameworky. Existují ale moduly, které umožňují běh pod
webovým serverem Apache a tedy i na Aise na adrese www.fi.muni.cz
.
Po přečtení tohoto textu byste měli mít dost informací pro to,
abyste zvolili pro vás vhodné řešení.
Než budete pokračovat, doporučujeme vám prostudovat si návody
Uživatelské HTML stránky,
Vytváření CGI skriptů,
a Návod k použití PHP na FI.
Předpokládáme, že Apache má přístup do adresáře public_html
.
CGI
CGI je jednoduché rozhraní, které lze využít v libovolném programovacím jazyce. V tomto návodu využijeme modul cgi-node, který poskytuje základní funkce pro jednodušší práci s HTTP požadavky a odpověďmi.
Nejprve vytvoříme adresáře pro naši novou aplikaci a podpůrné programy:
mkdir --parents ~/public_html/node-app/cgi-bin
Stáhneme knihovnu cgi-node
a nastavíme jí právo na spuštění:
cd ~/public_html/node-app/cgi-bin
wget -O cgi-node.cgi https://github.com/DEDAjs/cgi-node/releases/download/v0.2/cgi-node.js
chmod u+x cgi-node.cgi
Pak v ní změníme cestu k Node.js binárce na prvním řádku na /usr/bin/node
a nastavíme cestu k adresáři se session soubory (proměnnou SessionPath
)
na /tmp
:
sed -i "1s|.*|#!/usr/bin/node|" cgi-node.cgi
sed -i "s|SessionPath:.*|SessionPath: '/tmp/'|" cgi-node.cgi
Samotnou aplikaci uložíme do souboru index.js
. Zavoláme v ní jen
funkci CgiNodeInfo()
, která se hodí pro testování a vypisuje
informace o prostředí, HTTP dotazu a session:
cd ~/public_html/node-app
echo "CgiNodeInfo();" > index.js
Jednoduchou "Hello world" aplikaci byste napsali takto:
response.headers['Content-Type'] = 'text/plain; charset=utf-8';
write("Hello world!\n");
Více podrobností o použití node-cgi
zjistíte v dokumentaci
nebo ve zdrojovém kódu cgi-node.js
.
Nakonec řekneme webovému serveru Apache, že má všechny soubory s příponou .js
spouštět pomocí cgi-node.cgi
. Zde i v dalším textu nahraďte xlogin
vlastním loginem.
cd ~/public_html/node-app
cat > .htaccess <<'EOF'
AddHandler cgi-node .js
Action cgi-node /~xlogin/node-app/cgi-bin/cgi-node.cgi
DirectoryIndex index.js
EOF
Ověřte funkčnost aplikace navštívením https://www.fi.muni.cz/~xlogin/node-app/index.js
.
V aplikaci můžete využít i další moduly. Buď zadejte plnou cestu k nim
(/home/xlogin/...
) nebo je instalujte do adresáře ~/public_html/node-app/cgi-bin
,
protože se hledají relativně k umístění cgi-node.cgi
:
cd ~/public_html/node-app/cgi-bin
npm install wonderful-module
FastCGI
Při použití CGI brzy narazíte na limity této technologie. Každý HTTP požadavek je zpracován nově spuštěným procesem, což v případě Node.js znamená poměrně velkou latenci. Navíc nemůžete využít žádný z řady frameworků, které ke svému fungování potřebují modul http.
Naštěstí existuje modul node-fastcgi, který je postaven na specifikaci FastCGI. Tato umožňuje webovému serveru nechat dlouhodobě spuštěný proces obsluhovat více HTTP požadavků po sobě.
Nejprve si připravte adresář s aplikací, ve kterém nainstalujte modul node-fastcgi
:
mkdir --parents ~/public_html/node-fastcgi-app
cd ~/public_html/node-fastcgi-app
npm install node-fastcgi
Samotná aplikace index.js
může vypadat takto (převzato z dokumentace):
#!/usr/bin/node
var fcgi = require('node-fastcgi');
var server = fcgi.createServer(function(req, res) {
if (req.method === 'GET') {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end("Hello, world!\n");
} else if (req.method === 'POST') {
res.writeHead(200, { 'Content-Type': 'text/plain' });
var body = "";
req.on('data', function(data) { body += data.toString(); });
req.on('end', function() {
res.end("Received data:\n" + body);
});
} else {
res.writeHead(501);
res.end();
}
});
server.listen();
Skriptu je nutné dát práva pro vykonání (x
) pro vlastníka:
chmod u+x index.js
Nakonec řekneme webovému serveru Apache, že má .js
soubory spouštět
pomocí FastCGI:
cat > .htaccess <<'EOF'
AddHandler fastcgi-script .js
AddType application/x-httpd-javascript .js
DirectoryIndex index.js
EOF
Vyzkoušet její funkčnost můžete na adrese https://www.fi.muni.cz/~xlogin/node-fastcgi-app/
.
Express
FastCGI server můžete použít jako náhradu za modul http
.
Jako příklad uvedeme použití s frameworkem Express.
Tento framework nejdříve nainstalujeme (platí poznámky o umístění modulů
ze sekce CGI — hledají se relativně ke skriptu):
cd ~/public_html/node-fastcgi-app
npm install express
Aplikace pak může vypadat následovně:
#!/usr/bin/node
var fcgi = require('node-fastcgi');
var express = require('express');
var app = express();
app.get('/~xlogin/node-express-app/', function (req, res) {
res.set('Content-Type', 'text/plain');
res.send("Hello World!\n");
});
fcgi.createServer(app).listen();
a dostupná bude na https://www.fi.muni.cz/~xlogin/node-express-app/
.
Pěkná URL
Aby se vám a uživatelům vaší aplikace dobře pracovalo s URL,
doporučujeme nastavit si v souboru .htaccess
přepisování
URL pomocí mod_rewrite:
cat >> .htaccess <<'EOF'
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !^/~xlogin/node-express-app/index.js
RewriteRule (.*) /~xlogin/node-express-app/index.js/$1 [L,PT]
EOF
Zde řádek s RewriteRule
zajišťuje, že URL tvaru
www.fi.muni.cz/~xlogin/node-express-app/LIBOVOLNY_SUFFIX
budou obsloužena aplikací uloženou v index.js
.
Řádek s RewriteCond
zabraňuje nekonečnému cyklu přepisování.
Vaši aplikaci můžete například napojit metodou use
pod daný
prefix a používat tak cesty nezávislé na konkrétním umístění aplikace:
#!/usr/bin/node
var prefix = '/~xlogin/node-express-app';
var fcgi = require('node-fastcgi');
var express = require('express');
var base_app = express();
var app = express();
app.get('/hello', function (req, res) {
res.set('Content-Type', 'text/plain');
res.send("Hello\n");
});
app.get('/world', function (req, res) {
res.set('Content-Type', 'text/plain');
res.send("World!\n");
});
base_app.use(prefix, app);
fcgi.createServer(base_app).listen();
Vyzkoušet můžete adresy https://www.fi.muni.cz/~xlogin/node-fastcgi-app/hello
a https://www.fi.muni.cz/~xlogin/node-fastcgi-app/world
.
© Text věnující se CGI vychází z návodu Patrika Vala.