FastCGI

Psaní CGI nebo FastCGI aplikací není s využitím knihovny libfcgi a jejich bindingů do Haskellu FastCGI žádný problém. V tomto článku si ukážeme jednoduchý příklad fastcgi aplikace, která reaguje na Ajaxové requesty.

Následující příklad vznikl na základě článku, který jsem na toto téma našel.

Zdrojový kód

Pro jednoduchost pracuji pouze s obyčejnými řetězci, ale existují i knihovny pro JSON.

module Main where
 
-- bindingy na libfcgi
-- http://hackage.haskell.org/cgi-bin/hackage-scripts/package/fastcgi-3001.0.2
import Network.FastCGI
 
import Data.Maybe (fromMaybe)
 
-- prace s casem
import System.Time
import System.Locale (defaultTimeLocale)
 
-- spusti smycky obsluhujici fastcgi dotazy
main = runFastCGI echo
 
echo :: CGI CGIResult
echo = do
    cmd <- getInput "command"
    outStr <-
        case cmd of
            -- obsluha prikazu 'echo'
            Just "echo" -> do
                str <- getInput "text"
                return $ fromMaybe "N/A" str
 
            -- obsluha prikazu 'time'
            Just "time" ->
                liftIO $ formatTime =<< getClockTime
 
            -- promenna 'command' je nastavena na neznamy prikaz
            Just c ->  return $ "Neznamy prikaz '" ++ c ++ "'"
 
            -- v postBody nebyla nalezena promenna 'command'
            _      -> return "Zadej prikaz, hulvate!"
 
    -- vratime klientovi vysledek
    setHeader "Content-type" "application/x-javascript"
    output outStr
 
 
formatTime ctime =
    return . formatCalendarTime defaultTimeLocale "%H:%M:%S" =<< toCalendarTime ctime

Kompilace a použití

Máme-li nainstalované ghc a FasCGI, pak můžeme příklad zkompilovat příkazem

ghc --make Main.hs -o main.fcgi

Příklad volání z html vidíme na následujícím příkladu. Pro ajaxové volání jsem zde použil javascriptový framework Prototype.

<html>
<head>
<script type="text/javascript" src="prototype.js"/></script>
<script type="text/javascript">
 
function echo(text) {
    new Ajax.Request("main.fcgi", {
        asynchronous: true,
        method: 'post',
        postBody: 'command=echo&text=' + text,
        onComplete: function(response) {
            alert(response.responseText);
        },
        evalScripts: false});
}
 
function cas() {
    new Ajax.Updater('cas', "main.fcgi", {
        asynchronous: true,
        method: 'post',
        postBody: 'command=time',
        evalScripts: false});
}
</script>
</head>
 
<body>
   <br/>
   <span style="padding: 10px; border: 1px solid" onclick="echo('foobar');">echo</span>
   <span style="padding: 10px; border: 1px solid" onclick="cas();">Kolik je?</span>
   <span id="cas">nevim</span>
</body>
</html>

Efektivita programu

Možná by se zde hodilo uvést nějaké výsledky benchmarků, ale nejsem si jistý o vypovídací hodnotě u tak jednoduchého programu. Faktem ale je, že kompilátor ghc většinou generuje co do rychlosti mnohem efektivnější kód než jazyky, které se pro web běžně používají (viz. The Computer Language Benchmarks Game). Paměťová náročnost také není nikterak velká (FreeBSD 6.2):

#ps aux
...
www     2432  0.0  0.1  3052  1240  ??  I    12:05PM   0:00.00 /root/code/ajax/ajax-simple/main.fcgi
...

Tedy tento příklad v paměti zabírá něco málo pod 3 MB.

Kompletní příklad

Kompletní příklad obsahující zdrojový kód, ukázkové html, Makefile a konfigurační soubor pro lighttpd můžete stáhnout zde.

V případě, že máte nainstalované potřebné knihovny, stačí změnit cesty v lighttpd.conf (vše, co začíná na /root/code/ajax/ajax-simple/) a zadat

make run

, což program skompiluje a spustí lighttpd na portu 8080. Testovací příklad bude dostupný na URL http://localhost:8080/test.html.

knihovny/fastcgi.txt · Poslední úprava: 2009/04/15 10:41 (external edit)
Nahoru