2009-10-14 13 views

Odpowiedz

6

HTTP::Lite Metoda request umożliwia określenie wywołania zwrotnego.

Parametr $data_callback, jeśli jest używany, jest sposobem filtrowania danych po ich otrzymaniu lub obsługi dużych transferów. Musi to być odwołanie do funkcji i zostanie przekazane: odwołanie do instancji żądania http wywołującego wywołanie zwrotne, odwołanie do bieżącego bloku danych, które ma zostać dodane do treści, oraz parametr $cbargs (który może być wszystkim). Musi zwracać odwołanie do danych, które mają zostać dodane do treści dokumentu, lub undef.

Jednak patrząc na źródło, nie wydaje być błąd w sub request tym, że wydaje zignorować przeszła zwrotnego. To wydaje bezpieczniejsze w użyciu 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; 
} 

wyjściowa:

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

wygląda jak zwrotnego przekazanego do metody request jest traktowany inaczej:

#!/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

Niesamowite, to mogłoby wyjaśniać, dlaczego nie ważne co robiłem dokumenty, które wróciłem, były 0 bajtów. – cgp

+1

Zgłoszenie błędu: https://rt.cpan.org/Ticket/Display.html?id=50498 –

+0

Obie były dobre, ale użyłem tego. – cgp

2

Event::Lib da łatwy interfejs do najszybszej asynchronicznej metody IO r platforma.

IO::Lambda jest również całkiem niezły do ​​tworzenia szybkich, responsywnych aplikacji IO.

+1

Uh, trzymaj z AnyEvent. – jrockway

+0

Nie wiedziałem o tym module. Wygląda świetnie! –

9

Dobra stara LWP pozwala przetwarzać wynik jako strumień.

Np. Tutaj jest wywołanie zwrotne do funkcjiFunc, odczytywanie/przekazywanie bajtów bajtów do każdego wywołania do funkcjiFunc (możesz pominąć ten parametr, jeśli nie obchodzi Cię, jak duże są dane dla każdego połączenia, i po prostu chcesz przetworzyć strumień tak szybko jak to możliwe):

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, to mogło zadziałało, nie miałem okazji wypróbować tego, ponieważ inna odpowiedź zadziałała zanim miałem szansę to zaimplementować. – cgp

+0

Hah, ja * wiedziałem * to! Po prostu nie mogłem go znaleźć w dokumentach, więc wymazałem odpowiedź na wpół nałogową :) – Ether

+0

@Nie też tego nie pamiętałem, ale zauważ, że 'LWP' i' LWP :: Simple' to różne bestie. –

2

Czekaj, nie rozumiem. Dlaczego wykluczasz oddzielny proces? To:

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

z pewnością wygląda na "najprostszy sposób" do mnie. Jest to z pewnością łatwiejsze niż inne sugestie tutaj ...

+0

Nie jestem tego pewien, ale czy ten blok nie zostanie wyświetlony, dopóki curl nie odczyta pełnej odpowiedzi? –

+0

Nie, curl wypluwa, gdy się pojawia; nie buforuje niczego w pamięci. Możesz zweryfikować siebie, chwytając duży plik i obserwując rozmiar procesu zwijania podczas ładowania. –

+0

Wolę nie tworzyć wątków, ale poza tym jest to dobre rozwiązanie. – cgp

Powiązane problemy