5. Basic functions

The javadoc generated files are available on line on the ivy web site, and should be included in your ivy java package (or in /usr/share/doc/libivy-java, alongside with this very manual). Here are more details on those functions.

5.1. Initialization an Ivy object and joining the bus

Initializing a java Ivy agent is a two step process. First of all, you must create an fr.dgac.ivy.Ivy object. It will be the repository of your agent name, network state, subscriptions, etc. Once this object is created, you can subscribe to the various Ivy events: text messages through perl compatible regular expressions, other agents' arrival, departure, subscription or unsubscription to regexps, direct messages or die command issued by other agents. At this point, your ivy application is still not connected. In order to join the bus, call the start(string domain) method on your Ivy object. This will spawn two threads that will remain active until you call the stop() method on your Ivy object or until some other agent sends you a die message. Once this start() method has been called, the network machinery is set up according to the ivy protocol, and your agent is ready to handle messages on the bus !

fr.dgac.ivy.Ivy(String name,String message, IvyApplicationListener appcb)
This constructor readies the structures for the software bus connexion. It is possible to have more than one bus at the same time in an application, be it on the same ivy broadcast address or one different ones. The name is the name of the application on the bus, and will by transmitted to other application, and possibly be used by them (through String IvyClient.getApplicationName()). The message is the first message that will be sent to other applications, with a slightly different broadcasting scheme than the normal one ( see The Ivy architecture and procotol document for more information. If message is null, nothing will be sent. Usually, other application subscribe to this ready message to trigger actions depending on the presence of your agent on the bus. The appcb is an object implementing the IvyApplicationListener interface. Its different methods are called upon arrival or departure of other agents on the bus, or when your application itself leaves the bus, or when a direct message is sent to your application. It is also possible to add or remove other application listeners using the Ivy.AddApplicationListener() and Ivy.RemoveApplicationListener() functions.
public void start(String domainbus) throws IvyException
This method connects the Ivy bus to a domain or list of domains. This spawns network managing threads that will be stropped with Ivy.stop() or when a die message is received. The rendez-vous point is the String parameter domainbus, an UDP broadcast address like "10.0.0:1234" (255 are added at the end to become an IPv4 UDP broadcast address). This will determine the meeting point of the different applications. For the gory details, this is done with an UDP broadcast or an IP Multicast, so beware of routing problems ! You can also use a comma separated list of domains, for instance "10.0.0.1234,192.168:3456". If the domain is null, the API will check for the property IVY_BUS (set at the invocation of the JVM, e.g $ java -DIVY_BUS=10:4567 myApp, or via an environment variable on older JVMs); if not present, it will use the default bus, which is 127.255.255.255:2010. The default address requires a broadcast enabled loopback interface to be active on your system (CAUTION, on MacOSX and some releases of SunOS, the default bus doesn't work ...). If an IvyException is thrown, your application is not able to send or receive data on the specified domain.
public void stop() 
This methods stops the threads, closes the sockets and performs some clean-up. If there is no other thread running, the program quits. This is the preferred way to quit a program within a callback (please don't use System.exit() before having stopped the bus, even if it works ... ). Note that it is still possible to reconnect to the bus by calling start() once again.

5.2. Emitting messages

Emitting a message is much like echoing a string on a output channel. Portion of the message will be sent to the connected agent if the message matches their subscriptions.

public int sendMsg(String message) 
Will send each remote agent the substrings in case there is a regexp matching. The default behaviour is not to send the message to oneself ! The result is the number of messages actually sent. The main issue here is that the sender ivy agent is the one who takes care of the regexp matching, so that only useful information are conveyed on the network. Be sure that the message sent doesn't contains protocol characters: 0x01 to 0x08 and unfortunately 0x0D, the newline character. If you want to send newlines, see protectNewline, in advanced functions.

5.3. Subscription to messages

Subscribing to messages consists in binding a callback function to a message pattern. Patterns are described by regular expressions with captures. Since ivy-java 1.2.4, Perl Compatible Regular Expressions are used, with the Apache Jakarta Project regexp library (see the jakarta regexp web site). When a message matching the regular expression is detected on the bus (the matching is done at the sender's side), the recipient's callback function is called. The captures (ie the bits of the message that match the parts of regular expression delimited by brackets) are passed to the callback function much like options are passed to main. Use the bindMsg() method to bind a callback to a pattern, and the unbindMsg method to delete the binding.

public int bindMsg(String regexp, IvyMessageListener callback);
public void unBindMsg(int id);
The regexp follows the PCRE syntax (see man pcrepattern(3)), grouping is done with brackets. The callback is an object implementing the IvyMessageListener interface, with the receive method. The thread listening on the connexion with the sending agent will execute the callback.

There are two ways of defining the callback: the first one is to make an object an implementation of the IvyMessageListener interface, and to implement the public void receive(Ivyclient ic, String[] args) method. But this is limited to one method per class, so the second method used is the one of inner classes, introduced since java 1.1 and widely used in swing programs, for instance:

bindMsg("^a*(.*)c*$", new IvyMessageListener() {
  public void receive(IvyClient ic,String[] args) {
    ... // do some stuff
  }
});
The processing of the ivy protocol and the execution of the callback are performed within an unique thread per remote client. Thus, the callback will be performed sequentially. If you want an asynchronous handling of callbacks, see in the advanced functions.

5.4. Subscribing to application events

TODO