Cách dễ nhất (không mở một trình bao để cuộn tròn và đọc từ stdin) trong Perl để truyền từ một tài nguyên HTTP khác là gì? Tôi giả sử ở đây rằng tài nguyên HTTP tôi đang đọc là một luồng vô hạn tiềm tàng (hoặc chỉ thực sự, thực sự dài)Cách dễ nhất trong Perl tinh khiết để truyền từ một tài nguyên HTTP khác là gì?
Trả lời
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 Nó dường như an toàn hơn để sử dụng sub request
ở chỗ nó dường như bỏ qua gọi lại trôi qua.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";
}
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.
Uh, gắn bó với AnyEvent. – jrockway
Tôi không biết về mô-đun đó. No trông tuyệt! –
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
}
+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
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
@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. –
Đợ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 ...
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? –
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. –
Không nên tạo chủ đề, nhưng nếu không, đó là một giải pháp tốt. – cgp
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
Báo cáo lỗi được gửi: https://rt.cpan.org/Ticket/Display.html?id=50498 –
Cả hai đều tốt, nhưng tôi đã sử dụng báo cáo này. – cgp