За последние 24 часа нас посетили 55794 программиста и 1777 роботов. Сейчас ищут 723 программиста ...

Постоянное HTTP-соединение

Тема в разделе "Прочие вопросы по PHP", создана пользователем Raz0r, 26 авг 2008.

  1. Raz0r

    Raz0r Активный пользователь

    С нами с:
    26 авг 2008
    Сообщения:
    5
    Симпатии:
    0
    Здравствуйте.
    Мне нужно отправить два или более HTTP-запроса в рамках одного соединения, но не знаю, как это можно реализовать. Мне известно, что отправлять несколько запросов, используя одно и тоже подключение к серверу можно с помощью постоянных соединений (persistent connection), которые реализуются с использованием заголовка Connection: keep-alive в HTTP-запросе. Пробовал такой код:
    PHP:
    1. <?php
    2. $packet  = "GET / HTTP/1.0\r\n";
    3. $packet .= "Host: localhost\r\n";
    4. $packet .= "Connection: Keep-Alive\r\n\r\n";
    5. $fp = fsockopen( "127.0.0.1" , 80 , $errno , $errstr);
    6. if (!$fp) error ($errstr);
    7. fputs($fp , $packet);
    8. $resp = null;
    9. while (!feof($fp)) $resp .= fgets($fp);
    10.  
    11. $packet  = "GET / HTTP/1.0\r\n";
    12. $packet .= "Host: localhost\r\n";
    13. $packet .= "Connection: close\r\n\r\n";
    14. fputs($fp , $packet);
    15. $resp2 = null;
    16. while (!feof($fp)) $resp2 .= fgets($fp);
    17.  
    18. fclose($fp);
    19.  
    20. echo $resp."\r\n".$resp2;
    21. ?>
    Но производится только первый запрос. Как же сделать два запроса в одном соединении?
     
  2. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Постоянные соединения это HTTP/1.1, а у вас 1.0
     
  3. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Если не ошибаюсь, fsockopen не поддерживает keep-alive соединения.
     
  4. Raz0r

    Raz0r Активный пользователь

    С нами с:
    26 авг 2008
    Сообщения:
    5
    Симпатии:
    0
    Psih, для HTTP/1.1 keep-alive используется по умолчанию - в HTTP/1.0 keep-alive поддерживается, но нужно явно указывать тип соединения.
    Sergey89, а что же тогда поддерживает? socket_create?
     
  5. Raz0r

    Raz0r Активный пользователь

    С нами с:
    26 авг 2008
    Сообщения:
    5
    Симпатии:
    0
    Попробовал через socket - тот же результат
    Вот код:
    PHP:
    1. <?php
    2. $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    3. socket_set_option($socket,SOL_SOCKET,SO_KEEPALIVE,1);
    4. socket_connect($socket, '127.0.0.1', 80);
    5.  
    6. $packet  = "GET /test.php HTTP/1.1\r\n";
    7. $packet .= "Host: localhost\r\n";
    8. $packet .= "Connection: keep-alive\r\n\r\n";
    9. socket_write($socket, $packet);
    10. while ($out = socket_read($socket, 2048)) {
    11.     echo $out;
    12. }
    13.  
    14. $packet  = "GET /test.php HTTP/1.1\r\n";
    15. $packet .= "Host: localhost\r\n";
    16. $packet .= "Connection: keep-alive\r\n\r\n";
    17. socket_write($socket, $packet);
    18. while ($out = socket_read($socket, 2048)) {
    19.     echo $out;
    20. }
    21.  
    22. socket_close($socket);
    23. ?>
     
  6. Prizrak

    Prizrak Активный пользователь

    С нами с:
    26 авг 2008
    Сообщения:
    11
    Симпатии:
    0
    Я тоже ищу способ создать постоянное соединение, но ты делаешь как бы клиент, а я ещё и серверную часть. Мой пост можешь найти. Вообще что первый пример, что второй по сути одно и тоже. Различается только написание функций, а по работе они схожи.

    Функция fsockopen фактически заменяет первые функции во втором примере, создание сокета, соединение, и ещё обработка ошибок.

    Есть ещё функция psockopeno. Она схожа с fsockopen. Они имеют одинаковый набор параметров, но после выполнения psockopeno соединение будет сохранено даже после завершения работы сценария. Возможно тебе она подойдет. Но утверждать не берусь.

    А что на другой стороне, кто это принимает и обрабатывает?
     
  7. nimistar

    nimistar Активный пользователь

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    Хочу порассуждать... можно ?

    while (!feof($fp)) - читать пока не встретится конец файла или для соединений открытых при помощи fsockopen() -
    тоесть правило не будет выполняться и будет висеть пока не разорвется соединение ?

    while ($out = socket_read($socket, 2048)) - читать пока читается ? - тут посложнее, socket_read() возвращает текст или FALSE при ошибке , замечание socket_read() возвращает текст нулевой длины если нет больше данных для чтения - вот интересно данное выражение воспримет нулевой текст как ошибку или нет ? (строго говоря это же не ошибка ??)


    Вообщем есть два совета:
    1. Оставить в покое "KEEPALIVE" и юзать дедовским методом.
    2. Вытаскивать из хедера ответа длину вложения и рвать while по прочтению данного количества байт ...
     
  8. Raz0r

    Raz0r Активный пользователь

    С нами с:
    26 авг 2008
    Сообщения:
    5
    Симпатии:
    0
    веб-сервер
    nimistar, спасибо, Ваши рассуждения мне помогли.
    действительно, feof ждал тайм-аут и второй запрос не отправлялся.