Quel est le moyen le plus simple (sans ouvrir une coquille à courburer et à lire de stdin) dans Perl pour diffuser d'une autre ressource HTTP? Je suppose ici que la ressource HTTP que je lis est un flux potentiellement infini (ou vraiment vraiment très longtemps) p>
5 Réponses :
http :: lite 's Le paramètre sortie: demande code> la méthode vous permet de spécifier un rappel.
$ data_callback code>, s'il est utilisé, est un moyen de filtrer les données telles qu'elles sont reçues ou de gérer des transferts importants. Il doit s'agir d'une référence de fonction et sera transmis: une référence à l'instance de la requête HTTP faisant le rappel, une référence au bloc actuel des données sur l'objet d'une addition du corps et du
$ cbargs code> paramètre (qui peut être n'importe quoi). Il doit renvoyer une référence aux données à ajouter au corps du document, ou non. P>
blockquote>
Cependant, en regardant la source, il semble em> un bug dans sous demande code> dans lequel il semble em > Pour ignorer le rappel transduit. s> IT semble em> plus sûr d'utiliser
set_callback code>: p>
#!/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";
}
Impressionnant, cela semblerait expliquer pourquoi peu importe ce que je faisais, les documents que je revenais étaient 0 octets.
soupir b> Il semble qu'une fonction de rappel donnée à demande code> est traitée différemment de celle définie à l'aide de
set_callback code> et les documents ne l'expliquent pas correctement. .
LWP a également un mécanisme de rappel.
événement :: lib vous donnera une interface facile à l'asynchrone la plus rapide Méthode io pour votre plate-forme. P>
IO :: Lambda est également assez agréable pour la création rapide, réactive, Applications IO. P>
Je ne savais pas à propos de ce module. Cela semble très bien!
Bon vieux LWP vous permet de traiter le résultat comme un flux.
par exemple, voici un rappel sur votre proscunc, lecture / passe de byte_count octets à chaque appel à Yourfunc (vous pouvez supprimer ce paramètre si vous ne vous souciez pas de la manière dont les données sont importantes à chaque appel, et veulent simplement traiter le flux comme rapide possible): p>
+1, cela peut avoir travaillé, je n'ai pas eu la chance de l'essayer comme l'autre réponse travaillée avant d'avoir eu la chance de mettre en œuvre cela.
Hah, je
@ETETH Je ne me suis pas souvenu de cela non plus mais note que lwp code> et
lwp :: simple code> sont des bêtes différentes.
Attendez, je ne comprends pas. Pourquoi éliminez-vous un processus distinct? Ceci:
open my $stream, "-|", "curl $url" or die; while(<$stream>) { ... }
Je ne suis pas sûr de cela, mais ce block ne sera-t-il pas là que CURL ait lu la réponse complète?
Non, Curl crache la sortie car elle l'obtient; Il ne tamponne rien en mémoire. Vous pouvez vous vérifier en attrapant un fichier volumineux et en regardant la taille du processus de curl lors de la charge.
Préfère de ne pas créer les threads, mais sinon, c'est une solution fine.
Sauf si vous avez plusieurs gigabits de bande passante disponibles sur votre boîte, vous aurez Toujours B> Soyez limitée lorsque vous tirez des ressources réseau. Le travail de la CPU impliquée dans le frai d'un processus est un bruit incontournable. Je soupçonne fortement que vous optimisez prématurément.
Voici une version que j'ai terminée via NET :: http
Ceci est essentiellement une copie de l'exemple de la page NET :: HTTP Man / Perl Doc P>
use Net::HTTP; my $s = Net::HTTP->new(Host => "www.example.com") || die $@; $s->write_request(GET => "/somestreamingdatasource.mp3"); my ($code, $mess, %h) = $s->read_response_headers; while (1) { my $buf; my $n = $s->read_entity_body($buf, 4096); die "read failed: $!" unless defined $n; last unless $n; print STDERR "got $n bytes\n"; print STDOUT $buf; }