Persistentní HTTP připojení

Školení, která pořádám

Protokol HTTP ve verzi 1.1 zavádí persistentní připojení, které se dá použít k významnému urychlení požadavků na webový server. Prohlížeče tento mechanismus transparentně využívají a s trochou šikovnosti ho můžeme použít i v PHP:

<?php
/** Stažení stránky protokolem HTTP s využitím persistentních konexí
* @param string doménové jméno serveru
* @param string požadovaná cesta
* @param int port pro připojení
* @return array ($status, $headers, $body) nebo false v případě chyby
*/
function get_page($host, $path, $port = 80) {
    static $fp = false, $host_prev = "", $port_prev = 0;
    
    if (!$fp || get_resource_type($fp) != "stream" || feof($fp) || $host != $host_prev || $port != $port_prev) {
        $fp = fsockopen($host, $port);
        if (!$fp) {
            return false;
        }
        $host_prev = $host;
        $port_prev = $port;
    }
    fwrite($fp, "GET $path HTTP/1.1\r\n");
    fwrite($fp, "Host: $host\r\n");
    fwrite($fp, "\r\n");
    
    // zde bude načtení statusu do řetězce $status
    // zde bude načtení hlaviček do pole $headers = array("hlavička" => array("hodnota", ...), ...)
    // zde bude načtení těla přesné délky v závislosti na hlavičce Content-Length nebo Transfer-Encoding: chunked do řetězce $body
    
    if (isset($headers["connection"]) && in_array("close", $headers["connection"])) {
        fclose($fp); // jinak se používají persistentní konexe
    }
    return array($status, $headers, $body);
}
?>

Ve funkci je ponechána pouze část zajišťující využití persistentních připojení, načtení statusu, hlaviček a přesné délky těla nechám zase někdy na příště.

Nové připojení se otevře v případě, že je funkce volaná poprvé nebo se minule otevření nepodařilo (!$fp), spojení bylo ukončeno (get_resource_type), dospělo na svůj konec (feof) nebo minulému připojení neodpovídá adresa nebo port.

Persistentní připojení se dá využívat ještě intenzivněji – na server můžeme vychrlit své požadavky bez čekání na jeho odpověď a příchozí data zpracovávat až následně. Ale vzhledem k tomu, že server může spojení kdykoliv ukončit a my bychom museli požadavky posílat znovu, je už tento způsob na zpracování o něco náročnější.

Pokud naopak persistentní připojení využívat nechceme, je možné poslat hlavičku Connection: close.

Přijďte si o tomto tématu popovídat na školení Výkonnost webových aplikací.

Jakub Vrána, Seznámení s oblastí, 15.3.2006, diskuse: 8 (nové: 0)

Diskuse

PHX:

Zajimeve. Jen by me zajimalo zda by to slo vyuzit na obousmernou komunikaci. Neco jako telnet. Nebo jeste lepsi priklad by byl chat. Ze by se stranka nemusela reloudovat kazdych X sekund, ale pri zmene by server poslal data.

ikona Jakub Vrána OpenID:

Server push se takto realizovat nedá, ale možná by stálo za prozkoumání http://www.xulplanet.com/tutorials/mozsdk/serverpush.php.

C@esar:

Tady je ten chat, co hledate>
http://www.gtchat.de/news_en.xhtml

Leo:

"Jen by me zajimalo zda by to slo vyuzit na obousmernou komunikaci."

To by se klient (prohlizec v pc uzivatele) musel promenit v server. Leo

Dookie:

A proc nepouzit mod do apache?

ikona Jakub Vrána OpenID:

Rozšiřte nám obzory, jaký mod a jak ho použít?

Miroslav Bohovic:

Chcel by som sa opýtať či je možné použíť prezistentné pripojenie na long poll pri spojení klienta zo smartPhone na server.
Respektíve by ma zaujímalo akým spôsobom by bolo možné odsledovať náhle ukončenie aplikácie v smartPhone tak, aby sa vtedy ukončil aj long poll a aby sa ďalej nevykonával.
Skúšal som to pomocou
ďakujem connection_status() s využitím ignore_user_abort(TRUE) ale vôbec to nefunguje.

Ďakujem

ikona v6ak OpenID:

Není tam třeba nějaká proxy (klasická nebo reverzní), která by to podržela?

Diskuse je zrušena z důvodu spamu.

avatar © 2005-2024 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.