Hi there,
I'm trying to write a POE based server/client combo that uses SSL authed
persistent connections for comunication between a client and server.
Basically I have a server running that listens on port 2001. A client
connects to the server. Sets up an SSL connection with client
certificate auth and then what I _want_ to happen is that the client
then (every 10 seconds) asks for new temperature data from the server
and is served the current value. I have the client asking in a loop
every 10 seconds but the server isn't triggering and responding past the
first connection event. I'm not sure I'm doing this right (tm) can
anyone help me? I have some inline comments in the code.
client :
#!/usr/bin/perl
### very simple connect to server with auth certs and when connected
sends the "temp" command.
### then when it receives input it fires off Server input and wait 10
then sends again. But
### should it trigger a input event again? I think I'm looping in POE
incorrectly.
use warnings;
use strict;
use POE qw(Component::Client::TCP Filter::SSL);
POE::Component::Client::TCP->new(
RemoteAddress => "localhost",
RemotePort => 2001,
Filter => [ "POE::Filter::SSL", crt => 'keys/client1.crt',
key => 'keys/client1.key', client => 1 ],
Connected => sub {
$_[HEAP]{server}->put("temp");
},
ServerInput => sub {
my $command = "temp";
while(1) {
print "from server: ".$_[ARG0]."\n";
sleep (10);
print "Sending to server : $command\n";
$_[HEAP]{server}->put($command);
}
},
);
POE::Kernel->run();
exit;
Server code :
#!/usr/bin/perl
use strict;
use warnings;
use Socket;
use POE qw(
Wheel::SocketFactory
Wheel::ReadWrite
Driver::SysRW
Filter::SSL
Filter::Stackable
Filter::HTTPD
);
POE::Session->create(
inline_states => {
_start => sub {
my $heap = $_[HEAP];
$heap->{debug} = 1;
if ($heap->{debug}) { print "Stating POE session and
initialising socket\n"};
$heap->{listener} = POE::Wheel::SocketFactory->new(
BindAddress => 'localhost',
BindPort => 2001,
Reuse => 'yes',
SuccessEvent => 'socket_birth',
FailureEvent => '_stop',
);
if ($heap->{debug}) { print "Socket initialised Waiting for
connections\n"};
},
_stop => sub {
if ($_[HEAP]->{debug}) { print "Socket Binding Failed!\n"};
delete $_[HEAP]->{listener};
},
socket_birth => sub {
my ($socket) = $_[ARG0];
POE::Session->create(
inline_states => {
_start => sub {
my ($heap, $kernel, $connected_socket, $address, $port) =
@_[HEAP, KERNEL, ARG0, ARG1, ARG2];
$heap->{debug} = 1;
if ($_[HEAP]->{debug}) { print "Creating SSL Object\n"};
$heap->{sslfilter} = POE::Filter::SSL->new(
crt => 'keys/server.crt',
key => 'keys/server.key',
cacrt => 'keys/ca.crt',
cipher => 'DHE-RSA-AES256-GCM-SHA384:AES256-SHA',
debug => 1,
clientcert => 1
);
$heap->{socket_wheel} = POE::Wheel::ReadWrite->new(
Handle => $connected_socket,
Driver => POE::Driver::SysRW->new(),
Filter => $heap->{sslfilter},
InputEvent => 'socket_input',
ErrorEvent => '_stop',
);
if ($_[HEAP]->{debug}) { print "Connection made!\n"};
},
socket_input => sub {
my ($kernel, $heap, $buf) = @_[KERNEL, HEAP, ARG0];
print "RECEIVE : $buf\n";
my (@certid) = ($heap->{sslfilter}->clientCertIds());
my $content = '';
if ($_[HEAP]->{debug}) { print "Authing Client\n"};
if ($heap->{sslfilter}->clientCertValid()) {
if ($_[HEAP]->{debug}) { print "Client Certificate
Valid, Authorised\n"};
if ($buf eq "temp") {
$content =
`/home/pi/c0de/sht15/temp-munin.py`;
} else {
$content = "Unknown request\n";
}
my $response = $content;
if ($_[HEAP]->{debug}) { print "Sending Client
$content\n"};
$heap->{socket_wheel}->put($response);
return (1);
#$kernel->delay(_stop => 1);
} else {
if ($_[HEAP]->{debug}) { print "Client Certificate
Invalid, Rejecting connection\n"};
$content .= "INVALID CERT! Connection rejected!\n";
my $response = $content;
$heap->{socket_wheel}->put($response);
$kernel->delay(_stop => 1);
}
},
_stop => sub {
if ($_[HEAP]->{debug}) { print "Client Disconnected\n"};
delete $_[HEAP]->{socket_wheel};
}
},
args => [$socket],
);
}
}
);
$poe_kernel->run();
Any help anyone can provide would be awesome. I want to avoid
disconnecting and reconnecting ever time I want to get a reading. So
once the connection is made I want to be able to just send a request and
get an answer in an endless loop. I think this should work but can't
figure out why.
Thanks!