# $Id: Message.pm,v 1.6 2006/04/23 08:37:41 joern Exp $ #----------------------------------------------------------------------- # Copyright (C) 2002-2006 Jörn Reder . # All Rights Reserved. See file COPYRIGHT for details. # # This module is part of Event::RPC, which is free software; you can # redistribute it and/or modify it under the same terms as Perl itself. #----------------------------------------------------------------------- package Event::RPC::Message; use Carp; use strict; use Storable; my $DEBUG = 0; sub get_sock { shift->{sock} } sub get_buffer { shift->{buffer} } sub get_length { shift->{length} } sub get_written { shift->{written} } sub set_buffer { shift->{buffer} = $_[1] } sub set_length { shift->{length} = $_[1] } sub set_written { shift->{written} = $_[1] } sub new { my $class = shift; my ($sock) = @_; $sock->blocking(1); my $self = bless { sock => $sock, buffer => undef, length => 0, written => 0, }, $class; return $self; } sub read { my $self = shift; if ( not defined $self->{buffer} ) { my $length_packed; $DEBUG && print "DEBUG: going to read header...\n"; my $rc = sysread ($self->get_sock, $length_packed, 4); $DEBUG && print "DEBUG: header read rc=$rc\n"; die "DISCONNECTED" if !(defined $rc) || $rc == 0; $self->{length} = unpack("N", $length_packed); $DEBUG && print "DEBUG: packet size=$self->{length}\n"; die "Incoming message too big" if $self->{length} > 4194304; } my $buffer_length = length($self->{buffer}||''); $DEBUG && print "DEBUG: going to read packet... (buffer_length=$buffer_length)\n"; my $rc = sysread ( $self->get_sock, $self->{buffer}, $self->{length} - $buffer_length, $buffer_length ); $DEBUG && print "DEBUG: packet read rc=$rc\n"; return if not defined $rc; die "DISCONNECTED" if $rc == 0; $buffer_length = length($self->{buffer}); $DEBUG && print "DEBUG: more to read... ($self->{length} != $buffer_length)\n" if $self->{length} != $buffer_length; return if $self->{length} != $buffer_length; $DEBUG && print "DEBUG: read finished, length=$buffer_length\n"; my $data = Storable::thaw($self->{buffer}); $self->{buffer} = undef; $self->{length} = 0; return $data; } sub read_blocked { my $self = shift; my $rc; $rc = $self->read while not defined $rc; return $rc; } sub write { my $self = shift; my ($data) = @_; $DEBUG && print "DEBUG: going to write...\n"; if ( not defined $self->{buffer} ) { my $packed = Storable::nfreeze ($data); $self->{buffer} = pack("N", length($packed)).$packed; $self->{length} = length($self->{buffer}); $self->{written} = 0; } my $rc = syswrite ( $self->get_sock, $self->{buffer}, $self->{length}-$self->{written}, $self->{written}, ); $DEBUG && print "DEBUG: written rc=$rc\n"; return if not defined $rc; $self->{written} += $rc; if ( $self->{written} == $self->{length} ) { $DEBUG && print "DEBUG: write finished\n"; $self->{buffer} = undef; $self->{length} = 0; return 1; } $DEBUG && print "DEBUG: more to be written...\n"; return; } sub write_blocked { my $self = shift; my ($data) = @_; $self->write($data) and return; my $finished = 0; $finished = $self->write while not $finished; 1; } 1; __END__ =head1 NAME Event::RPC::Message - Implementation of Event::RPC network protocol =head1 SYNOPSIS # Internal module. No documented public interface. =head1 DESCRIPTION This module implements the network protocol of Event::RPC. Objects of this class are created internally by Event::RPC::Server and Event::RPC::Client and performs message passing over the network. =head1 AUTHORS Jörn Reder =head1 COPYRIGHT AND LICENSE Copyright (C) 2002-2006 by Joern Reder, All Rights Reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut