JADE学习【3】

Agent Communication

JADE Agent 通信基本原理

Agent之间的通信遵循FIPA规范,FIPA规范对Agent间的通信方式、通信策略与通信协议等均有规定。
共七层:网络基础设施层、传输层、报文传输协议层、消息封装层、Agent通信语言层、内容语言层、会话层。

远程机器上的Agent间的通信

编写通信程序的关键步骤是使用AID类设置接收方的名称和地址,远程通信亦是如此。AID类用来表示JADE的Agent标识符,JADE的内部Agent列表使用这个类记录Agent的名称和地址。可以使用该类的构造方法设置接收方的名称,使用该类的addAddresses()方法设置接收方的地址。
说明:

  • AMSAgentDescrip类
    该类是JADE.domain.FIPAAgentManagement.AMSAgentDescription包中的一个类,使用该类可获取AMS上所有Agent的列表,常用的方法是getName()。
  • SearchConstraints类
    该类是JADE.domain.FIPAAgentManagement.SearchConstraints包中的一个类,用来设置搜索的约束体条件。如,使用setMaxResults()设置查询的最大结果集。
  • AMSService类
    该类负责对agent中的管理,如使用该类的search()方法搜索AMS中的所有Agent。
package MyFirstAgent;

import jade.core.AID;
import jade.core.Agent;
import jade.lang.acl.ACLMessage;

public class remotesend extends Agent {
    @Override
    protected void setup() {
        ACLMessage msg=new ACLMessage(ACLMessage.INFORM);
        AID dest=new AID("receive@172.168.1.142:1099/JADE");
        dest.addAddresses("http://xxxxxx:xxxx/acc");
        msg.addReceiver(dest);
        msg.setContent("你好");
        send(msg);
    }
}

接收方:

package MyFirstAgent;

        import jade.core.Agent;
        import jade.core.behaviours.CyclicBehaviour;
        import jade.lang.acl.ACLMessage;

public class ReceiverAgent extends Agent {
    @Override
    protected void setup() {
        this.addBehaviour(new CyclicBehaviour() {
            @Override
            public void action() {
                ACLMessage msg=receive();
                if (msg!=null){
                    System.out.println("I received this message:"+msg.getContent()+",this message is from" +
                            msg.getSender());
                }
            }
        });
        System.out.println(getAID());
    }
}

输出:
( agent-identifier :name receive@172.168.1.142:1099/JADE  :addresses (sequence http://xxxxxx:xxxx/acc ))
I received this message:你好,this message is from( agent-identifier :name send@172.168.1.142:1099/JADE  :addresses (sequence http://xxxxxx:xxxx/acc ))

基于对象序列化机制的Agent间的通信

Agent间发送的消息从形式上说可以分为三类:
(1)原子消息。指以字符串形式发送的简单消息。
(2)Java对象。在很多情况下,Agent间发送的消息并非是简单的数值或字符串。例如发送图书的基本信息,就可以把书名、价钱、作者等属性封装在一个Book类中,然后把该图书作为Book类的对象,设置各属性值后作为消息发送出去。
(3)Ontology对象。即本体对象。对于一些复杂应用,用户需要为消息内容定义自己的词汇或语义,即Ontology。

消息内容的类型读消息内容的方法写消息内容的方法
字符串getContent()SetContent()
Java对象getContentObject()SetContentObject()
Ontology对象extractContent()fillContent()

消息模板

为实现对消息进行过滤,并创建不同的Behaviour分别处理来自不同Agent的不同种类的消息。
JADE提供了MessageTemplate类和接收方法,该接收方法将消息模板作为参数,并且只返回与消息模板匹配的消息。
MessageTemplate类利用MessageTemplate可以针对ACLMessage的每个属性设置模式,以达到过滤消息的目的。为了可以构建更复杂的匹配规则,多个模式也可以进行and,or,not运算。最有用的一些规则或方法包括:通信行为匹配、发送者匹配、会话ID匹配。例如,MatchPerformative(perforamtive)是通信行为的匹配,这里performative可能是:ACLMessage.INFORM、ACLMessage.PROPOSE或ACLMessage. AGREE等,还有发送者匹配MatchSender(AID)、会话匹配MatchConversationID(String)、通信协议匹配MatchProtocol(String)、本体匹配MatchOntology(String)等。
例如,建立一个消息模板,消息匹配规则为:消息原语是INFORM并且消息的发送者是"a1",则有:

MesssageTemplate mt = MessageTemplate.and(MessageTemplate.MatchPerformative(ACLMessage.INFORM
),MessageTemplate.MatchSender(new AID("a1",AID.ISLOCALNAME)));
//isGUID-指示传递的名称是否已经是全局唯一标识符。 还定义了两个常量ISGUID,
//ISLOCALNAME,用于设置此参数的值。 如果名称是本地名称,则将HAP(本地代理平台)
//连接到名称,并用“ @”分隔。
  public AID(String name, boolean isGUID) {
        this.addresses = new ArrayList(1);
        this.resolvers = new ArrayList(1);
        this.userDefSlots = new Properties();
        if (isGUID) {
            this.setName(name);
        } else {
            this.setLocalName(name);
        }

    }
    // boolean ISLOCANAME false
    //boolean ISGUID true

消息模板实例

例程包含两个Agent类:Template.class和Responder.class。程序运行时,启动两个Responder类的实例Agent,分别命名为A1和A2;同时也要启动一个Template类的实例Agent,命名为T1,如图:
在这里插入图片描述
首先,T1向A1和A2发送INFORM消息,消息内容为“ping”,测试是否能与这个两个Agent联通。A1和A2收到来自T1的“ping”消息后,创建并向T1发送回复消息,他们都会向T1发送两条具有不同原语的消息,T1利用消息模板过滤掉其他消息,只接收来自A1并具有Propose原语的消息。

Behaviour类的block()方法,与其名称的含义不同,block()方法并不是一个真正的阻塞命令,它只是将行为标记为“已阻塞”,使得Agent不再安排这个行为执行。当新消息插入到消息队列时,阻塞的行为被激活,再次执行处理接收到的消息 。
除了receive()方法,Agent类也提供和blockingReceive()方法,是真正阻塞了Agent线程,该方法还有一个重载版本,包含一个MessageTemplate参数(直到有与之匹配的模板时才返回)。在调用blockingReceive()返回命令前,它会阻止其他所有行为的执行。
ACLMessage类的方法createReply()自动创建一个新的ACLMEssage,并舍此那个接收者和其他控制对话的必要选项(conversation-id、reply-with、in-reply-to)
Template类:

package MySecondAgent;

import jade.core.AID;
import jade.core.Agent;
import jade.core.behaviours.CyclicBehaviour;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;

public class Template extends Agent {
    MessageTemplate mt1 = MessageTemplate.and(MessageTemplate.MatchPerformative(ACLMessage.PROPOSE),
            MessageTemplate.MatchSender(new AID("a1", AID.ISLOCALNAME)));

    @Override
    protected void setup() {
        //给a1和a2发送消息
        ACLMessage msg = new ACLMessage(ACLMessage.INFORM);
        msg.setContent("Ping");
        for (int i = 1; i <= 2; i++) {
            msg.addReceiver(new AID("a" + i, AID.ISLOCALNAME));
        }
        send(msg);
        //行为1 带过滤的
        addBehaviour(new CyclicBehaviour(this) {
            @Override
            public void action() {
                System.out.println("The message:");
                ACLMessage msg = receive(mt1);
                if (msg != null) {
                    System.out.println("gets " + msg.getPerformative() + " from " + msg.getSender().getLocalName() +
                            " = " + msg.getContent());
                } else {
                    System.out.println("gets NULL");
                }
                block();
            }
        });
        //接收全部消息
        /*addBehaviour(new CyclicBehaviour(this) {
            @Override
            public void action() {
                System.out.println("Behaviour two");
                ACLMessage msg = receive();
                if (msg != null) {
                    System.out.println("gets " + msg.getPerformative() + " from " + msg.getSender().getLocalName() +
                            " = " + msg.getContent());
                }
                else {
                    System.out.println("gets NULL");

                }
                block();
            }
        });
*/
    }
}


ResponderAgent类:

package MySecondAgent;

import jade.core.Agent;
import jade.core.behaviours.CyclicBehaviour;
import jade.lang.acl.ACLMessage;

public class ResponderAgent extends Agent {
    @Override
    protected void setup() {
        addBehaviour(new CyclicBehaviour() {
            @Override
            public void action() {
                ACLMessage msg=receive();
                if (msg!=null){
                    ACLMessage reply=msg.createReply();
                    reply.setPerformative(ACLMessage.INFORM);
                    reply.setContent("yes,i am here");
                    send(reply);
                    reply.setPerformative(ACLMessage.PROPOSE);
                    String msgcontent = "Tell me your opinion about"+reply.getSender().getLocalName();
                    reply.setContent(msgcontent);
                    send(reply);
                }
                block();
            }
        });
    }
}

输出(每次的结果不同,与线程有关系):
The message:
gets NULL
The message:
gets NULL
The message:
gets 11 from a1 = Tell me your opinion abouta1
The message:
gets NULL
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值