/usr/local/CPAN/Padre-Plugin-Swarm/Padre/Plugin/Swarm/Transport/Local/Multicast.pm
package Padre::Plugin::Swarm::Transport::Local::Multicast;
use strict;
use warnings;
use Wx qw( :socket );
use Padre::Wx ();
use Padre::Logger;
use base qw( Padre::Plugin::Swarm::Transport Padre::Role::Task );
use Padre::Plugin::Swarm::Transport::Local::Multicast::Service;
our $VERSION = '0.1';
use Class::XSAccessor
accessors => {
socket => 'socket',
service => 'service',
config => 'config',
token => 'token',
mcast_address => 'mcast_addr',
marshal => 'marshal',
};
*enable = \&connect;
*disable = \&disconnect;
sub connect {
my $self = shift;
# build the transmitting socket
my $mcast_address = Wx::IPV4address->new;
$mcast_address->SetHostname('239.255.255.1');
$mcast_address->SetService(12000);
$self->mcast_address($mcast_address);
# Local address
my $local_address = Wx::IPV4address->new;
$local_address->SetAnyAddress;
$local_address->SetService( 0 ); # 0 == random source port
my $transmitter = Wx::DatagramSocket->new( $local_address );
$self->socket( $transmitter );
# start the service thread listener
my $service = $self->task_request(
task => 'Padre::Plugin::Swarm::Transport::Local::Multicast::Service'
);
$self->service($service);
}
sub disconnect {
my $self = shift;
$self->socket->Destroy;
#$self->service->hangup;
# teardown the transmitting socket
# hangup the service thread
}
sub on_service_recv {
my ($self,$data) = @_;
TRACE( "On service recv with @_") if DEBUG;
## TODO - fix Padre::Service to have an event for started/stopped
if ( $data eq 'ALIVE' ) {
$self->on_connect->() if $self->on_connect;
return;
} elsif ( $data eq 'DEAD' ) {
$self->on_disconnect->() if $self->on_disconnect;
return;
}
my @messages = eval { $self->marshal->decode($data) };
if ( $@ ) {
TRACE( "Failed to decode data '$data' , $@" ) if DEBUG;
}
foreach my $m ( @messages ) {
$self->on_recv->( $m ) if $self->on_recv;
}
}
# Send a Padre::Swarm::Message
sub NOTsend {
my $self = shift;
my $message = shift;
$message->{token} ||= $self->{token};
my $data = eval { $self->marshal->encode( $message ) };
if ($@) {
TRACE( "Failed to encode $message - $@" ) if DEBUG;
return;
}
$self->write($data);
}
# Write encoded data to socket
sub write {
my $self = shift;
my $data = shift;
$self->socket->SendTo( $self->mcast_address, $data, length($data) );
}
1;