1 # -*- mode: cperl; cperl-indent-level:8; tab-width:8; indent-tabs-mode:t; -*-
5 # This file is part of Stem.
6 # Copyright (C) 1999, 2000, 2001 Stem Systems, Inc.
8 # Stem is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
13 # Stem is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with Stem; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 # For a license to use the Stem under conditions other than those
23 # described here, to purchase support for this software, or to purchase a
24 # commercial warranty contract, please contact Stem Systems at:
26 # Stem Systems, Inc. 781-643-7504
27 # 79 Everett St. info@stemsystems.com
31 #######################################################
33 package Stem::Inject ;
48 The hostname to use when connecting to the portal.
56 The port to use when connecting to the portal.
64 The cell to which the message is addressed.
72 This is the type of the message. It is used to select the delivery method in
80 This is used for the delivery method if the message type is 'cmd'.
87 The Stem::Codec module to use when creating packets.
94 This is the data the message is carrying. It should (almost) always be
103 The timeout before giving up on getting a reply from the portal, in
104 seconds. Defaults to 60.
109 'name' => 'wait_for_reply',
112 Indicates whether or not a reply is expected. Defaults to true.
122 my $self = Stem::Class::parse_args( $attr_spec, @_ ) ;
123 return $self unless ref $self ;
125 $self->{'from'} = "Stem::Inject:inject$$";
128 Stem::Packet->new( codec => $self->{'codec'} ) ;
130 local $SIG{'ALRM'} = sub { die 'Read or write to socket timed out' };
136 my $address = "$self->{'host'}:$self->{'port'}";
137 $self->{'sock'} = IO::Socket::INET->new($address) ;
138 $self->{'sock'} or die "can't connect to $address\n" ;
140 alarm $self->{'timeout'} if $self->{'timeout'} ;
144 $result = $self->_inject_msg() ;
151 return unless $self->{'wait_for_reply'};
158 my( $self, $data ) = @_ ;
161 Stem::Msg->new( from => $self->{'from'},
165 die $reg_msg unless ref $reg_msg ;
167 my $reg = $self->{'packet'}->to_packet($reg_msg) ;
169 my $written = syswrite( $self->{'sock'}, $$reg ) ;
170 defined $written or die "can't write to socket\n" ;
175 my $bytes_read = sysread( $self->{'sock'}, $read_buf, 8192 ) ;
177 defined $bytes_read or die "can't read from socket" ;
178 last if $bytes_read == 0 ;
180 my $data = $self->{'packet'}->to_data( $read_buf ) ;
191 ( 'to' => $self->{'to'},
192 'from' => $self->{'from'},
193 'type' => $self->{'type'},
196 $msg_p{'cmd'} = $self->{'cmd'} if $self->{'type'} eq 'cmd';
197 $msg_p{'data'} = $self->{'data'},
199 my $data_msg = Stem::Msg->new(%msg_p) ;
201 die $data_msg unless ref $data_msg ;
203 my $data = $self->{'packet'}->to_packet($data_msg) ;
205 my $written = syswrite( $self->{'sock'}, $$data ) ;
206 defined $written or die "can't write to socket\n" ;
208 return unless $self->{'wait_for_reply'};
213 my $bytes_read = sysread( $self->{'sock'}, $read_buf, 8192 ) ;
215 defined $bytes_read or die "can't read from socket" ;
216 last if $bytes_read == 0 ;
218 my $reply = $self->{'packet'}->to_data( $read_buf ) ;
220 return $reply->data ;
232 Stem::Inject - Inject a message into a portal via a socket connection
237 Stem::Inject->inject( to => 'some_cell',
238 type => 'do_something',
241 data => { foo => 1 },
244 # do something with data returned
248 This class contains just one method, C<inject>, which can be used to
249 inject a single message into a Stem hub, via a known server portal.
251 This is very useful if you have a synchronous system which needs to
252 communicate with a Stem system via messages.
260 This method is the sole interface provided by this class. It accepts
261 the following parameters:
265 =item * host (required)
267 This parameter specifies the host with which to connect.
269 =item * port (required)
271 The port with which to connect on the specified host.
273 =item * to (required)
275 The address of the cell to which the message should be delivered.
277 =item * type (required)
279 The type of the message to be delivered.
283 The cmd being given. This is only needed if the message's type is
288 The data that the message will carry, if any.
292 The codec to be used when communicating with the port. This defaults
293 to "Data::Dumper", but be careful to set this to whatever value the
294 receiving port is using.
296 =item * timeout (defaults to 60)
298 The amount of time, in seconds, before giving up on message delivery
299 or reply. This is the I<total> amount of time allowed for message
300 delivery and receiving a reply.
302 =item * wait_for_reply (defaults to true)
304 If this is true then the C<inject> method will expect a reply to the
305 message it delivers. If it doesn't receive one this will be
310 If there is an error in trying to inject a message, either with the
311 parameters given, or with the socket connection, then this method will
312 return an error string.
314 If no reply was expected, this method simply returns false.
315 Otherwise, it returns the reply message's data, which will always be a
322 Dave Rolsky <david@stemsystems.com>