2009-10-14 16 views

Trả lời

6

HTTP::Lite '' request phương pháp cho phép bạn chỉ định gọi lại.

Thông số $data_callback, nếu được sử dụng, là cách để lọc dữ liệu khi nhận hoặc xử lý chuyển lớn. Nó phải là một tham chiếu hàm và sẽ được thông qua: tham chiếu đến cá thể của yêu cầu http thực hiện gọi lại, tham chiếu đến khối dữ liệu hiện tại sắp được thêm vào phần thân và tham số $cbargs (có thể là bất kỳ thứ gì). Nó phải trả về tham chiếu đến dữ liệu để thêm vào phần thân của tài liệu, hoặc undef.

Tuy nhiên, nhìn vào nguồn, có dường như là một lỗi trong sub request ở chỗ nó dường như bỏ qua gọi lại trôi qua.dường như an toàn hơn để sử dụng 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; 
} 

Output:

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

Nó trông giống như một callback truyền cho phương thức request được xử lý khác:

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

Tuyệt vời, điều đó dường như giải thích tại sao không có vấn đề gì tôi đang làm các tài liệu tôi đã trở về là 0 byte. – cgp

+1

Báo cáo lỗi được gửi: https://rt.cpan.org/Ticket/Display.html?id=50498 –

+0

Cả hai đều tốt, nhưng tôi đã sử dụng báo cáo này. – cgp

2

Event::Lib sẽ cung cấp cho bạn một giao diện dễ dàng với phương thức IO không đồng bộ nhanh nhất cho bạn r nền tảng.

IO::Lambda cũng khá tốt để tạo các ứng dụng nhanh, đáp ứng, IO.

+1

Uh, gắn bó với AnyEvent. – jrockway

+0

Tôi không biết về mô-đun đó. No trông tuyệt! –

9

LWP cũ tốt cho phép bạn xử lý kết quả dưới dạng luồng. Ví dụ, đây là một cuộc gọi lại đến yourFunc, đọc/chuyển byte_count byte cho mỗi cuộc gọi đến yourFunc (bạn có thể bỏ tham số đó nếu bạn không quan tâm dữ liệu lớn đến từng cuộc gọi như thế nào và chỉ muốn xử lý luồng đó càng nhanh càng tốt):

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, điều này có thể đã làm việc, tôi đã không có cơ hội để thử nó như là câu trả lời khác làm việc trước khi tôi đã có cơ hội để thực hiện điều này. – cgp

+0

Hah, tôi * biết * nó! Tôi chỉ không thể tìm thấy nó trong tài liệu vì vậy tôi xóa câu trả lời nửa assed của tôi :) – Ether

+0

@Ether Tôi không nhớ điều này, nhưng lưu ý rằng 'LWP' và' LWP :: Simple' là những con thú khác nhau. –

2

Đợi đã, tôi không hiểu. Tại sao bạn lại loại trừ một quy trình riêng biệt? Điều này:

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

chắc chắn trông giống như "cách dễ nhất" với tôi. Nó chắc chắn dễ dàng hơn so với các đề xuất khác ở đây ...

+0

Tôi không chắc chắn về điều này nhưng sẽ không chặn cho đến khi curl đã đọc phản ứng hoàn chỉnh? –

+0

Không, uốn cong đầu ra khi nó nhận được; nó không đệm bất cứ thứ gì trong bộ nhớ. Bạn có thể tự xác minh bằng cách lấy một tệp lớn và xem kích thước quá trình cuộn tròn khi nó tải. –

+0

Không nên tạo chủ đề, nhưng nếu không, đó là một giải pháp tốt. – cgp