[SP-pm] Socket - algumas questões:

Andre Carneiro andregarciacarneiro at gmail.com
Tue May 3 12:30:09 PDT 2011


Faaala Stan!

Então, eu pensei mesmo em usar o AnyEvent, mas eu acho que é demais para o
problema que é bem simples. Na verdade esse daemon que eu estou fazendo vai
cuidar de dois processos apenas. Um que vai ficar organizando uma fila e
outro que só vai escutar comandos enviados via socket, que depois vão
despachar workers do gearman. Esse sim vai fazer a parte 'pesada' da coisa.
Então quanto a escalabilidade, eu pretendo jogar nas costas do gearman, e
não do daemon.

Mas ainda não descartei a possibilidade de usar o AnyEvent. Mesmo porque o
Solli também recomendou que eu usasse um framework que já cuidasse dessa
comunicação bi-derecional ...

Thx a lot!


Cheers!


2011/5/3 Stanislaw Pusep <creaktive at gmail.com>

> Yaih Carneiro!
> Que eu me lembre, accept() precisa retornar 2 sockets: accept(Client,
> Server). Você pode, sim, ler e gravar no socket do client, mas no server
> devem ser separados.
> Um aviso: seu código terá sérios problemas de escalabilidade por causa do
> fork(). E, como vc já deve prever, eu recomendaria o fabuloso AnyEvent :D
> Veja um servidor HTTPD toscão que aguenta 100 conexões simultâneas sem
> apelar p/load descomunal:
>
> https://gist.github.com/781246
>
> ABS()
>
>
>
> 2011/5/3 Andre Carneiro <andregarciacarneiro at gmail.com>
>
>> Salve Monges!
>>
>>
>> Estou com uns problemas com Sockets que mesmo fuçando bastante eu não
>> consegui resolver. Os sockets tanto do lado do servidor quanto do lado do
>> cliente estão ok, e isso significa:
>>
>> - O 'socket' do lado do 'client' escreve coisas no socket
>> - O 'socket' do lado do server lê coisas do Socket;
>>
>> Agora eu preciso que o socket do lado do servidor envie os resultados como
>> mensagens de erros e dados, de maneira geral, para o client. O que tá
>> rolando agora:
>>
>>
>> SERVER:
>>
>> <code>
>> use strict;
>> use warnings;
>> use IO::Socket::INET
>> use Daemon::Generic;
>> use feature qw/ say switch /;
>> .
>> .
>> .
>> #configuração
>> .
>> .
>> .
>>     my $usock = IO::Socket::INET->new (
>>                             Type => SOCK_STREAM ,
>>                             LocalAddr => $config_socket->{ SocketBind },
>>                             LocalPort => $config_socket->{ SocketPort },
>>                             Proto => 'tcp',
>>                             Listen => 1,
>>                             ReuseAddr => 1,
>>                 ) or die $!;
>>
>>
>>   my $pid = fork;
>>       if(!defined($pid)){
>>         say "FATAL! Sem recursos para o fork! Abortando!";
>>         exit 0;
>>     }
>>     elsif($pid == 0){
>>         my $newconn = &get_conn();
>>         while(1){
>>             #uma 'pá' de coisa aqui no child...
>>             sleep 60;
>>         }
>>         exit(1);
>>     }
>>     else {
>>         my $r = undef;
>>         while(1){
>>             say "I'm working!";
>>             if( $r = $usock->accept ){
>>                 &process_commands($r, \$usock);
>>             }
>>             else {
>>                 $logerr->write('error','Problemas com o socket!
>> Abortando!' . $!);
>>                 exit(0);
>>             }
>>             sleep 1;
>>         }
>> #        $usock->close;
>>         close $out;
>>
>>         waitpid($pid,0);
>>     }
>>
>>
>>
>> sub process_commands {
>>     my $sh = shift;
>>     my $rsock = shift;
>>     my $res = 0;
>>     while(<$sh>){
>>         #tratando o que vem do client
>>         my $out = $_ || 'none';
>>         $out =~ s/^(\ |\t)+//;
>>         my @params = split /\ +/, $out;
>>         my ($command,$parameter) = ( $params[0],$params[1] );
>>         #separando algumas informações
>>         my %client_auth_data = (    host     => undef,
>>                                     user     => undef,
>>                                     password => undef,
>>                                     port     => undef,
>>                         );
>>
>>         #Implementar a camada de autenticação aqui.
>>
>>         given($command){
>>             when( 'stopsafe' ){
>>                 say 'Executando o stopsafe';
>>                 if(!&pause_MTAs()){
>>                          #enviar mensagem de erro via socket
>>                 }
>>                 else {
>>                          #enviar mensagem de ok para o socket...
>>                 }
>>
>>                 $res = 1;
>>             }
>>             #mais uma pancada de comandos aqui...
>>             default {
>>                 my $msg = "Comando inválido! '$command $parameter' ";
>>             }
>>         }
>>     }
>>     return $res;
>> }
>>
>>
>>
>> </code>
>>
>>
>> Resumo: Eu tenho um processo que fica executando várias outras coisas, e
>> um outro só para ficar escutando comando vindo do socket do lado do CLIENT!
>> O que eu quero fazer, imagino eu, seria gravar alguma coisa no socket de
>> dentro dessa função 'process_commands'. E de alguma forma ler isso do
>> client.
>>
>>
>>
>> CLIENT
>>
>> <code>
>>     use strict;
>>     use warnings;
>>     use IO::Socket::INET;
>>     .
>>     .
>>     .
>>
>>     my ($bind, $port ) = @_;
>>     my $sock = IO::Socket::INET->new (
>>                                 PeerAddr => $bind,
>>                                 PeerPort => $port,
>>                                 Proto => 'tcp',
>>                                 Blocking    => 0,
>>                                 ReuseAddr   => 1,
>>                         ) or die $!;
>>
>>     $sock->send('chave1 valor1 chave2 valor2');
>>
>>     while(<$sock>){
>> #Teoricamente deveria ter alguma coisa no socket, mas nao rola...
>>     }
>>
>>     $sock->close();
>>
>>
>> </code>
>>
>>
>> Perguntas:
>>
>>
>> - Como gravar no socket do lado do server, de modo que isso seja legível
>> do lado do client?
>> - Preciso de protocolo específico para fazer isso ?
>> - Eu vi algumas pessoas usando udp ao invés de tcp alegando aumento de
>> performance, mas abrindo mão de vários quesitos de segurança dentre outros
>> problemas. Confirma?
>>
>>
>>
>>
>>
>>
>>
>> Cheers!
>>
>>
>>
>>
>> --
>> André Garcia Carneiro
>> Analista/Desenvolvedor Perl
>> (11)82907780
>>
>> =begin disclaimer
>>   Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>  SaoPaulo-pm mailing list: SaoPaulo-pm at pm.org
>>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>> =end disclaimer
>>
>>
>
> =begin disclaimer
>   Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>  SaoPaulo-pm mailing list: SaoPaulo-pm at pm.org
>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
> =end disclaimer
>
>


-- 
André Garcia Carneiro
Analista/Desenvolvedor Perl
(11)82907780
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.pm.org/pipermail/saopaulo-pm/attachments/20110503/a3ab0ba4/attachment.html>


More information about the SaoPaulo-pm mailing list