Pergunta


A classe HttpRequestPool proporciona uma solução. Muito obrigado a quem apontou isso.

Uma breve tutorial pode ser encontrada em: http: // www. phptutorial.info/?HttpRequestPool-construct


Problema

Eu gostaria de fazer concomitante / paralelas / simultânea solicitações HTTP em PHP. Eu gostaria de evitar pedidos consecutivos como:

  • um conjunto de pedidos vai demorar muito tempo para ser concluído; os mais pedidos o mais longo
  • o tempo limite de um meio caminho pedido através de um conjunto pode causar pedidos posteriores não deve ser feita (se um script tem um limite de tempo de execução)

Eu consegui encontrar detalhes para fazer simultaneuos [sic ] HTTP pedidos em PHP com a onda , no entanto eu gostaria de usar explicitamente do PHP funções HTTP se possível.

Especificamente, eu preciso de dados POST simultaneamente a um conjunto de URLs. Os URLs para o qual são postados dados estão fora do meu controle; eles são user-set.

Eu não me importo se eu precisar esperar por todas as solicitações para terminar antes as respostas podem ser processados. Se eu definir um tempo limite de 30 segundos em cada pedido e os pedidos são feitos simultaneamente, eu sei que devo esperar um máximo de 30 segundos (talvez um pouco mais) para todas as solicitações para ser concluído.

Não consigo encontrar detalhes de como isso pode ser alcançado. No entanto, eu notei recentemente uma menção no manual do PHP de PHP5 + ser capaz de lidar com solicitações HTTP simultâneas -. Eu pretendia fazer uma nota de que, no momento, esqueceu, e não pode encontrá-lo novamente

exemplo de pedido único (funciona bem)

<?php
$request_1 = new HttpRequest($url_1, HTTP_METH_POST);
$request_1->setRawPostData($dataSet_1);
$request_1->send();
?>

concomitante exemplo pedido (incompleta, claramente)

<?php
$request_1 = new HttpRequest($url_1, HTTP_METH_POST);
$request_1->setRawPostData($dataSet_1);

$request_2 = new HttpRequest($url_2, HTTP_METH_POST);
$request_2->setRawPostData($dataSet_2);

// ...

$request_N = new HttpRequest($url_N, HTTP_METH_POST);
$request_N->setRawPostData($dataSet_N);

// Do something to send() all requests at the same time
?>

Qualquer pensamento seria muito apreciada!

Clarificação 1 : Eu gostaria de ficar com as funções PECL HTTP como:

  • eles oferecem uma interface agradável OOP
  • eles são usados ??extensivamente na aplicação em questão e que adere ao que já está em uso deve ser benéfico do ponto de vista de manutenção
  • Eu geralmente tenho que escrever menos linhas de código para fazer uma solicitação HTTP usando as funções PECL HTTP em relação ao uso Curl - menos linhas de código também deve ser benéfico do ponto de vista de manutenção

Clarificação 2 : Eu percebo funções HTTP do PHP não são construídas dentro e talvez eu redigido coisas de forma errada lá, que vou corrigir. Eu não tenho preocupações sobre as pessoas terem de instalar material extra -. Isso não é uma aplicação que está a ser distribuído, é um aplicativo web com um servidor para si

Esclarecimento 3 :. Eu ficaria muito feliz se alguém afirma com autoridade que o PECL HTTP não pode fazer isso

Foi útil?

Solução

Eu tenho certeza HttpRequestPool é o que você está procurando para.

Para elaborar um pouco, você pode usar a bifurcação para conseguir o que você está procurando, mas que parece desnecessariamente complexa e não muito útil em um contexto HTML. Embora eu não testei, este código deve ser isso:

// let $requests be an array of requests to send
$pool = new HttpRequestPool();
foreach ($requests as $request) {
  $pool->attach($request);
}
$pool->send();
foreach ($pool as $request) {
  // do stuff
}

Outras dicas

Você tentou HttpRequestPool (é parte de HTTP)? Parece que ele iria reunir-se os objetos de solicitação e trabalhá-los. Eu sei que eu li em algum lugar que Http apoiaria pedidos simultâneos e para além de piscina não consigo encontrar nada.

Uma vez tive de resolver problemas semelhantes:. Fazendo várias solicitações sem acumulando os tempos de resposta

A solução acabou sendo uma função personalizada-build que usou sem bloqueio soquetes . Ele funciona assim:

$request_list = array(
  # address => http request string
  #
   '127.0.0.1' => "HTTP/1.1  GET /index.html\nServer: website.com\n\n",
   '192.169.2.3' => "HTTP/1.1 POST /form.dat\nForm-data: ...",
  );

foreach($request_list as $addr => $http_request) {
    # first, create a socket and fire request to every host
    $socklist[$addr] = socket_create();
    socket_set_nonblock($socklist[$addr]); # Make operation asynchronious

    if (! socket_connect($socklist[$addr], $addr, 80))
        trigger_error("Cannot connect to remote address");

    # the http header is send to this host
    socket_send($socklist[$addr], $http_request, strlen($http_request), MSG_EOF);
}

$results = array();

foreach(array_keys($socklist) as $host_ip) {
    # Now loop and read every socket until it is exhausted
    $str = socket_read($socklist[$host_ip], 512, PHP_NORMAL_READ);
    if ($str != "") 
        # add to previous string
        $result[$host_ip] .= $str;
    else
        # Done reading this socket, close it
        socket_close($socklist[$host_ip]);
}
# $results now contains an array with the full response (including http-headers)
# of every connected host.

É muito mais rápido desde reponses thunked são buscados no semi-paralelo desde socket_read não esperar a resposta, mas retorna se o socket-buffer ainda não está completo.

Você pode quebrar isso em interfaces de OOP apropriadas. Você irá necessidade de criar a string HTTP-solicitação de si mesmo, e processar a resposta do servidor é claro.

Um amigo me apontou para CurlObjects ( http://trac.curlobjects.com/trac ) recentemente, que eu achei muito útil para usar curl_multi.

$curlbase = new CurlBase; $curlbase->defaultOptions[ CURLOPT_TIMEOUT ] = 30; $curlbase->add( new HttpPost($url, array('name'=> 'value', 'a' => 'b'))); $curlbase->add( new HttpPost($url2, array('name'=> 'value', 'a' => 'b'))); $curlbase->add( new HttpPost($url3, array('name'=> 'value', 'a' => 'b'))); $curlbase->perform();

foreach($curlbase->requests as $request) { ... }

funções HTTP do PHP não são construídas em , qualquer um - eles são uma extensão PECL. Se a sua preocupação é que as pessoas ter que instalar material extra, ambas as soluções terão o mesmo problema - e enrolar é mais provável de ser instalado, eu imagino, como ele vem padrão com cada host que eu já estive em

Você pode usar pcntl_fork () para criar um processo separado para cada solicitação, em seguida, esperar por eles para acabar com:

http://www.php.net/manual/en /function.pcntl-fork.php

Existe algum motivo você não quiser usar cURL? As funções curl_multi_ * permitiria vários pedidos ao mesmo tempo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top