6
votes

Quel est le moyen le plus simple dans Pure Perl de diffuser d'une autre ressource HTTP?

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)


0 commentaires

5 Réponses :


6
votes

http :: lite 's demande code> la méthode vous permet de spécifier un rappel.

Le paramètre $ 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> xxx pré>

sortie:

#!/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";
}


3 commentaires

Impressionnant, cela semblerait expliquer pourquoi peu importe ce que je faisais, les documents que je revenais étaient 0 octets.


soupir Il semble qu'une fonction de rappel donnée à demande est traitée différemment de celle définie à l'aide de set_callback et les documents ne l'expliquent pas correctement. .


LWP a également un mécanisme de rappel.



2
votes

événement :: lib vous donnera une interface facile à l'asynchrone la plus rapide Méthode io pour votre plate-forme.

IO :: Lambda est également assez agréable pour la création rapide, réactive, Applications IO.


1 commentaires

Je ne savais pas à propos de ce module. Cela semble très bien!



9
votes

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): xxx


3 commentaires

+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 savait ça! Je ne pouvais tout simplement pas le trouver dans les docs alors j'ai effacé ma réponse à moitié appelle :)


@ETETH Je ne me suis pas souvenu de cela non plus mais note que lwp et lwp :: simple sont des bêtes différentes.



3
votes

Attendez, je ne comprends pas. Pourquoi éliminez-vous un processus distinct? Ceci:

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


4 commentaires

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 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.



0
votes

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;
}


0 commentaires