Ivy - Perl extension for implementing a software bus
use Ivy;
The Ivy perl module implements a software bus that provides easy communication between applications. Messages are broadcast as ASCII strings over a network defined by a list of domains and a port. Messages are received if they match a regular expressions and if your application is on the same network as remote ones. Before receive or send message you must call 'init', and 'new' class methods, followed by 'start' method. When you quit your application don't forget to call 'exit' class methods.
Ivy->init(...); Ivy::init(...);
Allows one to define global parameters which may be used as default ones at object creation time.
Parameters are :
Since V4.12, it is possible to use multicast (ie. with a domain between 224.0.0.0 and 239.255.255.255). You must be aware than when multicast is used, udp broadcast (defined in the -ivyBus paramter) are skipped. You should also probably avoid using the 244.x.x.x domain often used for networking management.
exit()
in the callback, Ivy will do it for you.
The prototype of your callback must be as follows:
sub MyCallback { my @parameters = @_; ... }
The prototype of your method must be as follows:
sub MyMethod { my ($self, @parameters) = @_; ... }
Example : Ivy->init(-loopMode =E<gt> 'TK', -appName =E<gt> 'MyWonderfulApp', -onDieFunc =E<gt> [\&restorecontext]);
Ivy::new(...); Ivy->new(...);
Check parameters, and create an Ivy bus object. You must call Ivy->init before creating a bus.
Parameters are :
exit()
in the callback, Ivy will do it for you.
The prototype of your callback must be as follows:
sub MyCallback { my @parameters = @_; ... }
The prototype of your method must be as follows:
sub MyMethod { my ($self, @parameters) = @_; ... }
Your callback could be:
sub MyCallback { my ($ref_array_present, $ref_array_absent, $ref_hash_present, $appname, $status, $host_or_regexp) = @_;
# $status is either new or died
my %present=%$ref_hash_present; foreach my $remoteapp (keys %present) { if ($present{$remoteapp} > 1) { print "n apps $remoteapp are presents on bus\n"; } } if ($status eq "new") { print "$appname connected from $host_or_regexp\n"; } elsif ($status eq "died") { print "$appname disconnected from $host_or_regexp\n"; } elsif ($status eq "subscribing") { print "$appname subscribes to $host_or_regexp\n"; } elsif ($status eq "unsubscribing") { print "$appname unsubscribed to $host_or_regexp\n"; } }
Example:
Ivy->new(-ivyBus => '156,157:2204', -onDieFunc => [\&restorecontext], -neededApp => ["DataServer", "HMI"], -statusFunc => \&MyCallback);
Ivy->mainLoop; Ivy::mainLoop;
Local main events loop. Use it if you don't use the Tk library.
$ivyobj->stop; Ivy::stop;
To stop the Ivy main loop.
$ivyobj->start; Ivy::start;
You must call this after you are ready to communicate through an Ivy bus and before you really communicate. The method returns the $ivyobj.
$ivyobj->sendMsgs(@messages); Ivy::sendMsgs(@messages);
Send a list of messages. A message should not contain a '\n' or it will not be delivered.
Example : $ivyobj->sendMsgs("Hello", "Don't Bother", "Y2K is behind us");
$ivyobj->sendAppNameMsgs(@messages); Ivy::sendAppNameMsgs(@messages);
Send a list of messages preceded by your application's name. A message should not contain a '\n' or it will not be delivered.
Example : $ivyobj->sendMsgs("Hello World"); # it will send "$appName Hello World" over the Ivy bus
$ivyobject->bindRegexp($regexp, [\&callback, @cb_parameters]); Ivy::bindRegexp($regexp, [\&callback, @cb_parameters]);
$ivyobject->bindRegexp($regexp, [$an_obj, \&method, @cb_parameters]); Ivy::bindRegexp($regexp, [$an_obj, \&method, @cb_parameters]);
This allows you to bind a regular expression to a
callback or method. The callback or method will be called for every
message that matches the regexp (case insensitive).
See perlre(1)
to find how to write regexps.
Use the bracketing construct ( ... ) so that your callback is
called with the captured bits of text as parameters.
To unbind callback(s)
associated to a regexp use bindRegexp with only
one argument, the regexp. Note that doing the same binding more than
once will induce multiple call of the same callback (this is usually a bug).
Example : $ivyobject->bindRegexp("\w+ (\d+)", [\&callback, @cb_parameters]);
# Your callback will be called with one more parameter which will be # the name of appli which send the message
# Your callback and method must be like: sub callback { my ($sendername, @cb_parameters, @matched_regexps_in_brackets) = @_; ... }
sub method { my ($self, $sendername, @cb_parameters, @matched_regexps_in_brackets) = @_; ... }
# to unbind: $ivyobject->bindRegexp("\w+ (\d+)");
$ivyobj->sendDirectMsgs($to, $id, @msgs); Ivy::sendDirectMsgs($to, $id, @msgs);
Send a message a message to appli $to. This appli must have done a bindDirect before to accept this message. regexp matching is not used with direct Messages. A message should not contain a '\n' or it will not be delivered.
$ivyobj->bindDirect($regexp, $id, [\&callback, @cb_parameters]); Ivy::bindDirect($id, [\&callback, @cb_parameters]);
The callback will be called with both the @msgs and the @cb_parameters.
Example : $ivyobject->bindDirectMessage("id1", [\&callback, @cb_parameters]);
# Your callback and method must be like: sub cb { my (@cb_parameters, @msgs) = @_; ... }
sub method { my ($self, @cb_parameters, @msgs) = @_; ... }
$ivyobj->sendDieTo($to); Ivy::sendDieTo($to);
Send a suicide to the application named $to.
$ivyobj->ping($to, $timeout); Ivy::ping($to, $timeout);
Send a ping message and wait until timeout to receive a pong.
$after_id = $ivyobj->after($timeAfter, \@callbacks_list); $after_id = Ivy::after($timeAfter, \@callbacks_list);
Call a list of callbacks after $timeAfter milliseconds. To be used only in conjonction with the 'LOCAL' Mainloop (see the Init method). When using the TK mainloop, you must use the Tk::after method.
$repeat_id = $ivyobj->repeat($timeAfter, \@callbacks_list); $repeat_id = Ivy:repeat($timeAfter, \@callbacks_list);
Have a list of callbacks repeatedly called every $timeAfter milliseconds. To be used only in conjonction with the 'LOCAL' Mainloop (see the Init method). When using the TK mainloop, you must use the Tk::repeat method.
$ivyobj->afterCancel($after_or_repeat_id); Ivy::afterCancel($after_or_repeat_id);
Cancel an after callback call. To be used only in conjonction with the 'LOCAL' Mainloop (see the Init method). When using the TK mainloop, you must use the Tk::afterCancel method.
$ivyobj->afterResetTimer($after_id); Ivy::afterResetTimer($after_id);
Reset a timer if this timer has not yet been triggered. To be used only in conjonction with the 'LOCAL' Mainloop (see the Init method).
$ivyobj->fileEvent($fd, $cb); Ivy::fileEvent($fd, $cb);
Add a fileEvent handler (or remove any handler associated to $fd if $cb paramter is omitted). The callback $cb will get the filehandle $fd as parameter. To be used only in conjonction with the 'LOCAL' Mainloop (see the Init method). When using the TK mainloop, you must use the Tk::fileevent method.
$ivyobj->DESTROY;
Destroy the $ivyobj object. No other method should be applied to the reference of this deleted object. This method should not be used directly.
The stop method does not work!
In the statusFunc, an agent is identified by its name which is not garantted as unique
A message to be sent should not contain '\n' char, because the '\n' is the message separator. Ivy.pm will detect and skip such messages.
No other known bugs at this time. If you find one, please report them to the authors.
perl(1), perlre(1), ivyprobe.pl(1)
Alexandre Bustico <bustico@cena.fr>, Herve Damiano <damiano@cena.fr>, Stephane Chatty <chatty@cena.fr>, Christophe Mertz <mertz@cena.fr>
CENA (C) 1997-2002