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í.
Diskuse je zrušena z důvodu spamu.