2009-10-14 6 views

Respuesta

6

HTTP::Lite El método request le permite especificar una devolución de llamada.

El parámetro $data_callback, si se usa, es una forma de filtrar los datos tal como se reciben o manejar grandes transferencias. Debe ser una referencia de función, y se aprobará: una referencia a la instancia de la solicitud http que realiza la devolución de llamada, una referencia al bloque actual de datos que se agregará al cuerpo y el parámetro $cbargs (que puede ser cualquier cosa)) Debe devolver una referencia a los datos para agregarlos al cuerpo del documento o undef.

Sin embargo, mirando a la fuente, no parece a un error en sub request en que parece hacer caso omiso de la devolución de llamada pasado. Se parece más seguro de usar set_callback:

#!/usr/bin/perl 

use strict; 
use warnings; 

use HTTP::Lite; 

my $http = HTTP::Lite->new; 
$http->set_callback(\&process_http_stream); 
$http->http11_mode(1); 

$http->request('http://www.example.com/'); 

sub process_http_stream { 
    my ($self, $phase, $dataref, $cbargs) = @_; 
    warn $phase, "\n"; 
    return; 
} 

Salida:

 
C:\Temp> ht 
connect 
content-length 
done-headers 
content 
content-done 
data 
done 

se ve como una devolución de llamada se pasa al método request es tratado de forma diferente:

#!/usr/bin/perl 

use strict; 
use warnings; 

use HTTP::Lite; 

my $http = HTTP::Lite->new; 
$http->http11_mode(1); 

my $count = 0; 
$http->request('http://www.example.com/', 
    \&process_http_stream, 
    \$count, 
); 

sub process_http_stream { 
    my ($self, $data, $times) = @_; 
    ++$$times; 
    print "$$times====\n$$data\n===\n"; 
} 
+0

Impresionante, eso parece explicar por qué no importaba lo que estaba haciendo los documentos que estaba devolviendo eran 0 bytes. – cgp

+1

Informe de error archivado: https://rt.cpan.org/Ticket/Display.html?id=50498 –

+0

Ambos fueron buenos, pero utilicé este. – cgp

2

Event::Lib dará Tiene una interfaz fácil para el método IO asíncrono más rápido para usted r plataforma.

IO::Lambda es también bastante agradable para crear aplicaciones IO rápidas y receptivas.

+1

Uh, quédate con AnyEvent. – jrockway

+0

No sabía sobre ese módulo. ¡Se ve genial! –

9

El buen LWP antiguo le permite procesar el resultado como una secuencia.

Por ejemplo, aquí hay una devolución de llamada a suFunc, leyendo/pasando byte_count bytes a cada llamada a suFunc (puede descartar ese parámetro si no le importa qué tan grande es la información para cada llamada, y solo quiere procesar la transmisión lo más rápido posible):

use LWP; 
... 
$browser = LWP::UserAgent->new(); 
$response = $browser->get($url, 
          ':content_cb' => \&yourFunc, 
          ':read_size_hint' => byte_count,); 
... 
sub yourFunc { 
    my($data, $response) = @_; 
    # do your magic with $data 
    # $respose will be a response object created once/if get() returns 
} 
+0

+1, esto pudo haber funcionado, no tuve la oportunidad de probarlo ya que la otra respuesta funcionó antes de que tuviera la oportunidad de implementar esto. – cgp

+0

¡Hah, yo * lo sabía *! Simplemente no pude encontrarlo en los documentos, así que borré mi respuesta a medias :) – Ether

+0

@Ether No recuerdo esto tampoco, pero tenga en cuenta que 'LWP' y' LWP :: Simple' son bestias diferentes. –

2

Espera, no entiendo. ¿Por qué estás descartando un proceso separado? Esto:

open my $stream, "-|", "curl $url" or die; 
while(<$stream>) { ... } 

me parece la "forma más fácil". Es ciertamente más fácil que las otras sugerencias aquí ...

+0

No estoy seguro de esto pero ¿no se bloqueará hasta que Curl haya leído la respuesta completa? –

+0

No, las salpicaduras de rizos salen como salen; no almacena nada en la memoria. Puede verificarse agarrando un archivo grande y observando el tamaño del proceso de curl mientras se carga. –

+0

Prefiere no crear los hilos, pero de lo contrario, es una buena solución. – cgp

Cuestiones relacionadas