Try checking to see what syswrite returns. Maybe your call is not writing all of buffer. If so syswrite will return how much it actually wrote. You could then used the offset parament of syswrite to continue to write the rest of the buffer. I have a similar app that writes data to a socket connection. Here is how I implement it...
#
# Sub used to write data to FDMS.
# Writing requires that the first 6 bytes are NBxxxx
# where xxxx is the total number of bytes to write plus the NBxxxx.
#
sub write {
my ($this, $buffer) = @_;
my $thisSub = (caller(0))[3];
my $socket = $this->{socket};
my $select = $this->{select};
my $verbose = $this->{verbose};
my $timeout = $this->{writeTimeout};
$buffer = sprintf('NB%04d%s', length($buffer) + 6, $buffer);
my $length = length($buffer);
my $offset;
my $bytes;
while ($length > 0) {
if ($select->can_write($timeout)) {
$bytes = $socket->syswrite($buffer, $length, $offset);
croak "Unable to write: $!" unless defined $bytes;
$offset += $bytes;
$length -= $bytes;
print "$thisSub($bytes) = $buffer\n" if $verbose;
}
else {
croak 'timeout on write';
}
}
}
UPDATE:
try putting in a signal handler for SIGPIPE to see if you can get around the problem.
Something like...
$SIG{PIPE} = sub { die "SIGPIPE\n"; };
...just to see if it is happening.
UPDATE:
See this post...
script dies with 'broken pipe'-message, even in eval | [reply] [d/l] [select] |
thanks for your input. I've tried the $SIG{PIPE} and it is dying so it is happening. I've tried to simplify it into the following:
Module (Voice.pm):
package Voice;
use IO::Socket;
sub new {
shift;
my $self = {};
bless($self);
return $self;
} # end-new
sub talk {
$handle = IO::Socket::INET->new(Proto => "tcp",
PeerAdr => "localhost",
PeerPort => 1314)
|| die($!);
print $handle "(SayText \"Testing.\")" || die($!);
} # end-talk
1;
Script (test.cgi):
#!/usr/bin/perl
use CGI qw(:header);
print header;
use Voice;
my $voice = new Voice;
$voice->talk;
exit;
When I run test.cgi through a web browser I get nothing (even if the festival server is not running). When I run it from the command line, I get "broken pipe" regardless of whether the festival server is running or not.
The following script works just fine:
#!/usr/bin/perl
use IO::Socket;
$handle = IO::Socket::INET->new(Proto => "tcp",
PeerAddr => "localhost",
PeerPort => 1314)
|| die($!);
print $handle "(SayText \"Testing.\")";
exit;
Being a newbie at perl modules my guess is that I've done something wrong in writing the module but I really dont know. | [reply] [d/l] [select] |
UPDATED from original post.
I tried you're simpler test script with $voice->talk, and it wouldn't even work without cgi. If you find the answer, let us know. I'm interested in learning about using sockets in modules, and there seems to be a trick to it, which eludes me. Like you it works from a conventional script. I did get it working from a simple procedural style module, but as soon as I put the $socket into a $self->{CONN} form, it gives a broken pipe. It has to be they way the socket gets stored in the scalar. Either a reference to the scalar needs to be used, or the socket needs to be stored as a full
fledged hash? I just started reading my Object Oriented Perl, but hav'nt got far enough yet. :-)
package Voice2;
use IO::Socket;
$handle = IO::Socket::INET->new(Proto => "tcp",
PeerAddr => "localhost",
PeerPort => 1314)
|| die($!);
sub talk {
print $handle "(SayText \"Testing.\")";
}
1;
Test script
#!/usr/bin/perl
use lib '.';
use Voice2;
Voice2::talk;
exit;
I'm not really a human, but I play one on earth.
flash japh
| [reply] [d/l] [select] |
Hi, well I played abit with it, and got something that works. :-) Now I'm not an expert on OO programming, so just take this as is. From what I can observe, there is somekind of problem when you you set $self->{CONN} = undef in new(), and then try to redefine it in open. So I removed the open() method, and it works from the commandline. In your cgi, there may be additional complications because of the server.
Anyways, here is a working module and test script.
package Voice;
use strict;
use warnings;
require IO::Socket;
#################################################
# Method: Voice->new
# Description: Object Constructor method
#################################################
sub new {
# bless a new object
shift;
my $self = {};
bless($self);
# Set params passed for the object
my ( $server, $port ) = ( 'localhost', 1314 );
# ::: Set Object Parameters ::: #
$self->{ERROR} = undef; # error (duh!)
$self->{SERVER} = $server; # festival server
$self->{PORT} = $port; # festival port
$self->{PRO} = 'tcp'; # connection protocol
$self->{CONN} = IO::Socket::INET->new(
Proto => "tcp",
PeerAddr => "localhost",
PeerPort => 1314)
|| die($!);
# return the object
return $self;
} # end-new
# -----------------------------------------------
#################################################
# Method: Voice->speak
# Description: say the sentence
#################################################
sub speak {
# set as method
my $self = shift;
# read in the sentence
my ($sentence) = @_;
# my $buffer = "(SayText \"" . $sentence . "\")\n";
my $buffer = "(SayText \"" . $sentence . "\")";
#print "$buffer\n";
# say the sentence
if ( syswrite( $self->{CONN}, $buffer, length($buffer) ) ) {
} # end-if
else {
# set the error string
$self->{ERROR} = "Could not say sentence!";
} # end-else
} # end-prepare
# -----------------------------------------------
#################################################
# Method: Voice->close
# Description: close the festival connection
#################################################
sub close {
# set as method
my $self = shift;
# close the IO::Socket::INET connection
shutdown( $self->{CONN}, 2 );
close( $self->{CONN} );
} # end-close
# -----------------------------------------------
1;
#test script
#!/usr/bin/perl
use warnings;
use strict;
use lib '.';
use Voice;
my $voice = Voice->new;
$voice->speak( 'foobar foobar foobar' );
$voice->close;
I'm not really a human, but I play one on earth.
flash japh
| [reply] [d/l] [select] |
Try looking at the CPAN module that connects to a Festival server.
http://search.cpan.org/~rcaley/speech_pm_1.0/Speech/Festival.pm
If you are still interesting in writing your own you can look into how it was implemented to see were you might be going wrong. | [reply] |