Basic Message Passing

In this tutorial, we create a simple message-passing algorithm, in which a selected node disseminates a piece of information to all the other nodes (through multi-hop). As usual, the algorithm is coded through the three following steps:

  1. Create a class that extends Node
  2. Override some methods, namely onStart(), onSelection(), onMessage()
  3. Tell JBotSim to use this class

Here is the code of our algorithm, followed by some explanations.

import io.jbotsim.core.Message;
import io.jbotsim.core.Color;
import io.jbotsim.core.Node;

public class BroadcastNode extends Node {

    boolean informed;

    @Override
    public void onStart() {
        informed = false;
        setColor(null);
    }

    @Override
    public void onSelection() {
        informed = true;
        setColor(Color.RED);
        sendAll(new Message("My message"));
    }

    @Override
    public void onMessage(Message message) {
        if (! informed) {
            informed = true;
            setColor(Color.RED);
            sendAll(new Message(message.getContent()));
        }
    }
}

Execution and test

Before executing this algorithm, we tell the topology that this class is the default node model. We also set the duration of a round to 500ms (for the sake of visualization) via setTimeUnit().

import io.jbotsim.core.Topology;
import io.jbotsim.ui.JViewer;

public class Main{
    public static void main(String[] args){
        Topology tp = new Topology();
        tp.setDefaultNodeModel(BroadcastNode.class);
        tp.setTimeUnit(500);
        new JViewer(tp);
        tp.start();
    }
}

The program can be executed by right-clicking anywhere around this code and selecting Run 'Main.main()' (subsequent runs can be done through the "play" icon in the top bar). When the program starts, you should see an empty window in which you can add nodes and play with them.

As you can see, the nodes are colored in red. This is due to the execution of onStart() on each node after it is added to the topology. You can select the source node by Middle-Clicking (or Ctrl+Clicking) on it, causing onSelection() to be executed on that node. You should now see the propagation occurring through the network.

The Message API

Some observations:

  1. The above example uses the sendAll() method, whose effect is to send the given message to all the local neighbors. It is also possible to send a message to a single neighbor using send().
  2. The arrival of a message causes onMessage() to be called on the receiving node. A node may possibly receive several messages in the same round, causing as many invocations of onMessage() (sequentially).
  3. By default, communications are synchronous and every message takes one unit of time (i.e. one round) to arrive. It is also possible to use asynchronous message passing.
  4. The content of a message is any object. Therefore, on the destination side, it is often necessary to cast the content of the message towards its original class.
  5. When different kinds of messages are used, it is possible to assign a flag that helps filtering what part of your code is concerned with it.
  6. A node can choose to receive messages as they arrive, using onMessage() as above, or to retrieve all of them at once for the current round, by calling getMailbox() from another method, e.g. from onClock().

All these aspects are covered in the Advanced Message Passing tutorial.

Regarding initialization

At this point, you may have a few other questions about initialization, such as:

  1. Can we create topologies by another mean than the mouse?
  2. Can we wait for the topology to be entirely set up before starting the nodes?
  3. Is there a way to select a distinguished node by program rather than clicking on it?

→ Essentially, all the answers are yes, as covered in the Topology Setup and Node Initialization tutorial.

Next tutorial: Making the nodes move

In the above example, the nodes are static. We will now see how to make them move in the Basic Movement and Timing tutorial.