package Net::OpenSoundControl::Server;

use 5.006;
use strict;
use warnings;
use IO::Socket;
use Net::OpenSoundControl;

our @ISA = qw();

our $VERSION = '0.02';

=head1 NAME

Net::OpenSoundControl::Server - OpenSound Control server implementation


  use Net::OpenSoundControl::Server;
  use Data::Dumper qw(Dumper);

  sub dumpmsg {
      my ($sender, $message) = @_;
      print "[$sender] ", Dumper $message;

  my $server = Net::OpenSoundControl::Server->new(
      Port => 7777, Handler => \&dumpmsg) or
      die "Could not start server: $@\n";



This module implements an OSC server (right now, blocking and not-yet multithreaded...) receiving messages via UDP.
Once a message is received, the server calls a handler
routine. The handler receives the host name of the sender as well as the (decoded) OSC message or bundle.

=head1 METHODS


=item new(Port => $port, Name => $name, Handler => \&handler)

Creates a new server object. Default port is 7123, default name is
C<Net-OpenSoundControl-Server:7123>, default handler is undef.

Returns undef on failure (in this case, $@ is set).


sub new {
    my $class = shift;
    my %opts  = @_;
    my $self  = {};

    $self->{PORT} = $opts{Port} || 7123;
    $self->{NAME} = $opts{Name}
      || 'Net-OpenSoundControl-Server:' . $self->{PORT};
    $self->{HANDLER} = $opts{Handler} || undef;

    $self->{SOCKET} = IO::Socket::INET->new(
        LocalPort => $self->{PORT},
        Proto     => 'udp')
      or return undef;    # error is in $@

    bless $self, $class;

=item name()

Returns the name of the server


sub name {
    my $self = shift;

    return $self->{NAME};

=item port()

Returns the port the server is listening at


sub port {
    my $self = shift;

    return $self->{PORT};

=item readloop()

Enters a loop waiting for messages. Once a message is received, the server will
call the handler subroutine, if defined.


sub readloop {
    my $self = shift;

    my $MAXLEN = 1024;
    my ($msg, $host);

    while ($self->{SOCKET}->recv($msg, $MAXLEN)) {
        my ($port, $ipaddr) = sockaddr_in($self->{SOCKET}->peername);
        $host = gethostbyaddr($ipaddr, AF_INET) || '';

        $self->{HANDLER}->($host, Net::OpenSoundControl::decode($msg))
          if defined $self->{HANDLER};

        return if ($msg =~ /exit/);



=head1 SEE ALSO

The OpenSound Control website:


=head1 AUTHOR

Christian Renz, E<lt>crenz @ web42.comE<gt>


Copyright 2004-2005 by Christian Renz E<lt>crenz @ web42.comE<gt>

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.