Samples
Getting Started
The Spread package is contained in a file, "spread.jar".
To use Spread from a Java application, this file should
be in your classpath. For Java 1.1, this is done by
making sure the directory containing spread.jar is
in the CLASSPATH enviornment variable. For Java2 this
is done by using the "-classpath" option on the command
line when compiling or running any classes that user
Spread. For applets, simply put spread.jar in the
same directory as the applet class. To access the
Spread classes from any classes you write, simply
include the following line at the top of the .java
file:
import spread.*;
Connecting/Disconnecting
To establish a connection to a spread daemon, use
the SpreadConnection class. First, create a new SpreadConnection
object, then use the connect() method to make a connection
to a daemon:
SpreadConnection connection = new SpreadConnection();
connection.connect(InetAddress.getByName("daemon.address.com"),
0, "privatename", false, false);
The first argument to connect() is an InetAddress,
which is a class in the package java.net. The static
method InetAddress.getByName() takes one argument,
a String object specifying an Internet address,
and returns an InetAddress object representing that
address. The address can be passed either by name
or by IP (A.B.C.D). Alternatively, if null is passed
as the first argument to connect(), an attempt will
be made to connect to a daemon on the localhost.
The second argument to connect() is the port to
connect to. If this is 0, the default port (4803)
will be used.
This connection can be used until the disconnect()
method is called, which terminates the connection
to the daemon.
connection.disconnect();
Aside from adding and removing listeners, no methods
should be called on a SpreadConnection before connect()
is called.
Joining/Leaving
To join a group on the connection, use the SpreadGroup
class. First, create a new SpreadGroup object, then
use the join() method to join a group:
SpreadGroup group = new SpreadGroup();
group.join(connection, "group");
The first argument to join() is the SpreadConnection
on which the group is joined. This must be specified
so that Spread knows which connection messages should
be received on. The second argument is the name
of the group to join.
Messages multicast to the group will be received
on the connection until the leave() method is called.
group.leave();
Multicasting
To multicast a message to one or more groups, use
the SpreadMessage class. First, create a new SpreadMessage
object:
SpreadMessage message = new SpreadMessage();
This creates a new outgoing message. Next, the
message data, the groups the message is going to,
and the type of delivery requested should be set:
message.setData(data);
message.addGroup("group");
message.setReliable();
The setData() method sets the message's data to
an array of bytes. Alternatives to setData() are
setObject() and digest(), each of which takes an
object that implements the Serializable interface.
setObject() is used for sending one Java object,
while repeatedly calling digest() can be used to
send multiple objects in one message. The addGroup()
method is used to specify a group to send the message
to. The setReliable() is used to set the delivery
method. Possible delivery methods are: unreliable,
reliable, fifo, causal, agreed, and safe. The setSelfDiscard()
method can be used to specify that this message
should not be sent back to the user who is sending
it. To actually send the message, use SpreadConnection's
multicast() method:
connection.multicast(message);
Receiving
To receive a message, use SpreadConnection's receive()
method.
SpreadMessage message = connection.receive();
receive() will block until a message is available.
When one is ready to be received, the message will
be read and placed into a new SpreadMessage object
which is returned by receive().
The isRegular() method can be used to check if the
message is a regular message. Otherwise, it is a
membership message. Membership messages will only
be received if they are request by passing true
as the final arguement to SpreadConnection's connect()
method. If the message is a regular message, the
get*() methods in SpreadMessage will provide more
information about the message. If the message is
a membership message, the getMembershipInfo() method
can be used to return a MembershipInfo object, which
provides information about the membership change.
if(message.isRegular())
System.out.println("New
message from " + message.getSender());
else
System.out.println("New
membership message from " + message.getMembershipInfo().getGroup());
MessageFactory
The MessageFactory class is a utility included with
the Java interface to Spread. An object of the MessageFactory
class is used to generate any number of outgoing messages
based on a default message. To use a message factory,
create a MessageFactory object, passing the default
message to the constructor.
messageFactory = new MessageFactory(message);
To change the default at a later time, use the
setDefault() method:
messageFactory.setDefault(message);
To get a message from the message factory, use
the createMessage() method:
SpreadMessage message = messageFactory.createMessage();
This will create a clone of the default message.
Message factories with more complex behavior can
be created by extending the MessageFactory class.
One example is a message factory that sets the message's
data to the current system time:
public class TimeStampMessageFactory extends
MessageFactory
{
public SpreadMessage createMessage()
{
SpreadMessage
message = super.createMessage();
message.setObject(new
Long(System.currentTimeMillis()));
return
message;
}
}
Listeners
In addition to using SpreadConnection's receive()
method, there is another way to receive messages.
This is by the use of two interfaces: BasicMessageListener
and AdvancedMessageListener. To use a listener, first
implement one of these two interfaces. Then add an
instance of your implementation to a connection with
one of SpreadConnection's add() methods:
connection.add(listener);
After being added to a connection, the listener
will be alerted whenever a new message is received
on the connection. BasicMessageListener's have one
callback method, messageReceived(), which is called
whenever a new message arrives. AdvancedMessageListener's
have two callback methods: regularMessageReceived()
is called whenever a regular message arrives, and
membershipMessageReceived() is called when a membership
message arrives. These methods will keep being called
until the listener is removed from the connection
with one of SpreadConnection's remove() methods:
connection.remove(listener);
There can be multiple listeners on a connection
at any one time. SpreadConnection's receive() should
not be called while the connection has any listeners.
Exceptions
When an error occurs in a Spread method, a SpreadException
is thrown. One example is if receive() is called on
a SpreadConnection() object before connect() is called
on that object. Another example is calling leave()
on a SpreadGroup object before calling join() on that
object. Any method that is declared as throwing a
SpreadException must be placed within a try-catch
block:
try
{
connection.multicast(message);
}
catch(SpreadException e)
{
e.printStackTrace();
System.exit(1);
}
If you do not want to handle specific exceptions,
but just want to exit with an error whenever a SpreadException
is thrown, you can place your main code within one
try-catch block:
public final static void main(String args[])
{
try
{
...
}
catch(SpreadException e)
{
e.printStackTrace();
System.exit(1);
}
}
More specific exceptions will probably be added
at some future point. These exceptions will be extended
from SpreadException, so code written to handle
SpreadExceptions will also be catch any future exceptions
that are added.
Applets
When using Java in an applet, there is usually a security
manager installed, which restricts what your code
is allowed to do. For example, when running an applet
in a web browser, the code is not allowed to make
Internet connections to any place other than the machine
running the web server. So, if Spread is running in
an applet, in a web browser, the spread daemon must
also be running on the machine running the web server.
The following code can be used, in the class that
extends Applet, to get an InetAddress object for the
machine running the web server:
InetAddress host = InetAddress.getByName(getCodeBase().getHost());
Samples
Two sample java applications are included with the
Spread interface for Java. User is an example of how
to write a simple user in Java. It is similar to the
C library sample, user.c. Flooder is an example of
a flooder that can help test performance. It is similar
to the C library sample, flooder.c.