四.外部应用程序调用Agent
JADE2.3以后的版本都提供了in-process接口来实现外部应用程序对agent的调用。
我们可以通过jade.core.Runtime.instance()来获得jade运行时的一个单独得实例。有两种方法可以用来创建一个jade主容器和一个jade远程容器。主要调用过程如下:
看一个稍微复杂的例子:
package examples.inprocess;
 
import jade.core.Runtime;
import jade.core.Profile;
import jade.core.ProfileImpl;
 
import jade.wrapper.*;
 
/**
   This class is an example of how you can embed JADE runtime
   environment within your applications.
 
   @author Giovanni Rimassa - Universita' di Parma
 
 */
public class InProcessTest {
 
 // Simple class behaving as a Condition Variable
 public static class CondVar {
    private boolean value = false;
 
    synchronized void waitOn() throws InterruptedException {
      while(!value) {
       wait();
      }
    }
 
    synchronized void signal() {
      value = true;
      notifyAll();
    }
 
 } // End of CondVar class
 
 
 // This class is a custom agent, accepting an Object through the
 // object-to-agent communication channel, and displying it on the
 // standard output.
 public static class CustomAgent extends jade.core.Agent {
 
    public void setup() {
      // Accept objects through the object-to-agent communication
      // channel, with a maximum size of 10 queued objects
      setEnabledO2ACommunication(true, 10);
 
      // Notify blocked threads that the agent is ready and that
      // object-to-agent communication is enabled
      Object[] args = getArguments();
      if(args.length > 0) {
       CondVar latch = (CondVar)args[0];
       latch.signal();
      }
 
      // Add a suitable cyclic behaviour...
      addBehaviour(new jade.core.behaviours.CyclicBehaviour() {
 
       public void action() {
        // Retrieve the first object in the queue and print it on
        // the standard output
        Object obj = getO2AObject();
        if(obj != null) {
           System.out.println("Got an object from the queue: [" + obj + "]");
        }
        else
           block();
       }
 
      });
    }
 
    public void takeDown() {
      // Disables the object-to-agent communication channel, thus
      // waking up all waiting threads
      setEnabledO2ACommunication(false, 0);
    }
 
 } // End of CustomAgent class
 
 public static void main(String args[]) {
 
    try {
 
      Runtime rt = Runtime.instance();//获取jade运行时
 
      // Exit the JVM when there are no more containers around
      rt.setCloseVM(true);
 
      // 看运行参数中是否有-container
      if(args.length > 0) {
       if(args[0].equalsIgnoreCase("-container")) {
        // 创建一个默认的profile
        Profile p = new ProfileImpl(false);
        //p.setParameter(Profile.MAIN, "false");
 
        // Create a new non-main container, connecting to the default
        // main container (i.e. on this host, port 1099)
      System.out.println("Launching the agent container ..."+p);
        AgentContainer ac = rt.createAgentContainer(p);
 
        // 创建一个新的agent
        AgentController dummy = ac.createNewAgent("inProcess", "jade.tools.DummyAgent.DummyAgent", new Object[0]);
 
        // 启动它
        System.out.println("Starting up a DummyAgent...");
        dummy.start();
 
        //等10秒
        Thread.sleep(10000);
 
        // 杀死这个agent
        System.out.println("Killing DummyAgent...");
        dummy.kill();
 
        // 在同一虚拟机上创建另一个容器,NB,
        // NB. 两个容器不能共享同一个 Profile对象!!! -->
        // 所以需再创建一个profile对象
        p = new ProfileImpl(false);
        //p.putProperty(Profile.MAIN, "false");
        AgentContainer another = rt.createAgentContainer(p);
 
        // 用两个参数创建一个移动agnet
        Object[] arguments = new Object[2];
        arguments[0] = "Hello World!";
        arguments[1]=dummy;
        AgentController mobile = another.createNewAgent("Johnny", "examples.mobile.MobileAgent", arguments);
        mobile.start();
 
        return;
       }
      }
 
      // 在8888端口运行一个完整的平台t
      // create a default Profile
      Profile pMain = new ProfileImpl(null, 8888, null);
 
      System.out.println("Launching a whole in-process platform..."+pMain);
      AgentContainer mc = rt.createMainContainer(pMain);
 
      // 使用默认的profile启动一个容器
      ProfileImpl pContainer = new ProfileImpl(null, 8888, null);
      System.out.println("Launching the agent container ..."+pContainer);
      AgentContainer cont = rt.createAgentContainer(pContainer);
      System.out.println("Launching the agent container after ..."+pContainer);
 
      System.out.println("Launching the rma agent on the main container ...");
      AgentController rma = mc.createNewAgent("rma", "jade.tools.rma.rma", new Object[0]);
      rma.start();
 
      // Launch a custom agent, taking an object via the
      // object-to-agent communication channel. Notice how an Object
      // is passed to the agent, to achieve a startup synchronization:
      // this Object is used as a POSIX 'condvar' or a Win32
      // 'EventSemaphore' object...
 
      CondVar startUpLatch = new CondVar();
 
      AgentController custom = mc.createNewAgent("customAgent", CustomAgent.class.getName(), new Object[] { startUpLatch });
      custom.start();
 
      // Wait until the agent starts up and notifies the Object
      try {
       startUpLatch.waitOn();
      }
      catch(InterruptedException ie) {
       ie.printStackTrace();
      }
          
 
      // Put an object in the queue, asynchronously
      System.out.println("Inserting an object, asynchronously...");
      custom.putO2AObject("Message 1", AgentController.ASYNC);
      System.out.println("Inserted.");
 
      // Put an object in the queue, synchronously
      System.out.println("Inserting an object, synchronously...");
      custom.putO2AObject(mc, AgentController.SYNC);
      System.out.println("Inserted.");
 
    }
    catch(Exception e) {
      e.printStackTrace();
    }
 
 }
 
}
 
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐