2009-05-13 7 views
1

Je travaille sur un projet pour mon entreprise qui utilise un serveur socket (php) pour collecter des données à partir d'un périphérique distant. Comment puis-je faire fonctionner ce programme perl directement sur le flux au lieu d'avoir d'abord écrire le serveur dans un fichier tmp puis d'exécuter ce script sur ce fichier puis d'écrire un fichier csv pour l'insérer dans une base de données? J'ai pensé à utiliser IO :: Socket mais je ne suis pas sûr de la façon de procéder.Besoin d'aide pour analyser les données de flux du serveur socket php avec perl

En outre, si quelqu'un a des conseils/indications sur la façon de nettoyer ce code, il serait apprécié. (Je suis encore très Perl un n00b ;-))

Voici ce que j'ai jusqu'à présent pour le perl prog (I avec deux enroule fichiers tmp après est exécuté).


#vim set sw=2 ts=2 
#!/usr/bin/perl 
use warnings; 
use strict; 
use Data::Dumper; 
&convert; 

#open the source file, strip out any unneeded chars, reformat the data 
sub convert{ 
    my $source = "$ARGV[0]"; 
    my $dest = "$ARGV[0]"."_tmp.txt"; 
    chomp $source; 
    open SOURCE, '', $dest or die "Could not open '$dest' $!"; 

    # move the data from the source file into an array 
    my %fields; 
    my @field_names = qw/FIELD1 FIELD2 FIELD3 FIELD4 FIELD5 FIELD6/; 
    my $pack_definition = 'a4 a2 a1 a4 a4 a8A*'; 
    while(){ 

     # strip out the packet header 
     s#T18##g; 
     s#T00##g; 
     s/^(FF14).*$//g; 
     s/^(FF18).*$//g; 
     s/(^|\n)[\n\s]*/$1/g; 

     # arrange the data into the necessary order 
     @fields{@field_names} = unpack($pack_definition, $_); 
     s#(FF15)(.{2})(.{1})(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})#$1\t$2\t$3\t$5$4\t$7$6\t$11$10$9$8#g; 
     s#(FF16)(.{2})(.{1})(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})#$1\t$2\t$3\t$4\t$5\t$6\t$7\t$8\t$9\t$10\t$11#g; 
     s#(FF17)(.{2})(.{1})(.{2})(.{2})(.{2})(.{2})(.{4})(.{4})#$1\t$2\t$3\t$5$4\t$7$6\t$8\t$9#g; 
     my @spds = /(FF15)\t(.{2})\t(.{1})\t(.{4})\t(.{4})\t(.{8})/; 

     # convert the data from hex to ascii 
     foreach my $data (@spds){ 
      my $replacement = hex($data); 
      s#$data#$replacement#g; 
     } 
     my @psis = /(FF16)\t(.{2})\t(.{1})\t(.{2})\t(.{2})\t(.{2})\t(.{2})\t(.{2})\t(.{2})\t(.{2})\t(.{2})/; 
     foreach my $data1(@psis){ 
      my $replacement1 = hex($data1); 
      s#$data1#$replacement1#g; 
     } 
     my @rates= /(FF17)\t(.{2})\t(.{1})\t(.{4})\t(.{1,4})\t(.{4})\t(.{4})/; 
     foreach my $data2 (@rates){ 
      my $replacement2 = hex($data2); 
      s#$data2#$replacement2#g; 
     } 

     # print the converted data to the destination file 
     print DEST; 
    } 
    # close the files 
    close SOURCE; 
    close DEST; 
} 
&create_vals; 

# perform conversion from raw values to human readable output 
sub create_vals{  
    my $source = "$ARGV[0]"."_tmp.txt"; 
    my $dest = "$ARGV[0]"."_converted.txt"; 
    chomp $source; 
    open SOURCE, '', $dest or die "Cannot open '$dest' for writing $!"; 
    while(){ 
     s#(65301)\t(.{2})\t(8)\t(.{1,5})\t(.{1,5})\t(.{1,4})#"'".$1."','". $2."','". $3."','". ($4/8)."','". ($5/8)."','". ($6/20)."'"#eg; 
     s#(65302)\t(.{2})\t(8)\t(.{1,3})\t(.{1,3})\t(.{1,3})\t(.{1,3})\t(.{1,3})\t(.{1,3})\t(.{1,3})\t(.{1,3})#"'".$1."','". $2."','". $3."','". $4."','". (($5*1.8)-40)."','". (($6*1.8)-40)."','". ($7*.58)."','".($8*.58)."','".($9*.29008)."','".(($10*1.8)-40)."','".$11."'"#eg; 
     s#(65303)\t(.{2})\t(8)\t(.{1,5})\t(.{1,5})\t(.{1,5})\t(.{1,5})#"'".$1."','". $2."','". $3."','". ($4*0.014)."','". ($5*.05)."'"#eg; 
     print DEST; 
    } 
} 
    close SOURCE; 
    close DEST; 
__END__ 

Répondre

1

Si "exécuter directement sur le flux" signifie "accepter les connexions d'un périphérique distant au lieu du serveur PHP", alors IO :: Socket est un moyen d'aller. Google a plenty of examples et vous pouvez également consulter la documentation perlipc.

+0

Je préfère garder l'application serveur séparée. Ce que je pensais était s'il y a un moyen d'exécuter ceci sur les données sans avoir à écrire autant de fichiers temporaires (ie Data arrive dans le serveur -> serveur écrit les données dans blah.txt -> programme perl ouvre blah.txt exécute et convertit puis écrit ces données dans blah_tmp.txt -> puis exécute & create_vals et écrit les données dans -> blah_converted.txt.) Si je pouvais juste le garder confiné afin qu'il s'exécute sur les données avant que le serveur ne l'écrive dans le fichier temporaire, puis écrit que données à la DB ce serait génial. – bsisco

+0

Si vous êtes en mesure de modifier l'application serveur, vous pouvez essayer d'appeler un script Perl depuis PHP comme décrit dans http://devzone.zend.com/article/1712. Une autre approche pourrait être de transmettre les données à votre script Perl via un tube, une autre socket, une base de données, etc. – Denys

+0

génial ..... merci pour l'info. Je vais essayer dès que j'aurai une chance ... – bsisco

Questions connexes