Hành vi BookNegotiator thảo luận trong Phần 3.2.5.1 đại diện cho một ví dụ về một hành vi thực hiện một cuộc hội thoại phức tạp. Một cuộc hội thoại là một chuỗi các thông điệp trao đổi giữa hai hay nhiều agent với những quan hệ nhân quả và tạm thời được định nghĩa rõ ràng. Hành vi BookNegotiator gửi một thông điệp CFP cho các agent (các agent bán được biết đến) và nhận được tất cả phản hồi. Sau đó, nếu nhận được ít nhất một phản hồi PROPOSE, nó phải gửi thêm một thông điệp ACCEPT_PROPOSAL (cho agent bán mà có lời đề xuất tốt nhất) và chờ xác nhận. Bất cứ khi nào một cuộc hội thoại như này phải được tiến hành thì đó là một sự thực hành tốt để xác định các trường kiểm soát hội thoại trong các thông điệp trao đổi bên trong hội thoại đó. Điều này cho phép dễ dàng tạo ra các mẫu rõ ràng phù hợp với những phản hồi có thể có.
private class BookNegotiator extends Behaviour { private String title;
private int maxPrice;
private PurchaseManager manager;
private AID bestSeller; // The seller agent who provides the best offer
private int bestPrice; // The best offered price
private int repliesCnt = 0; // The counter of replies from seller agents
private MessageTemplate mt; // The template to receive replies
private int step = 0;
public BookNegotiator(String t, int p, PurchaseManager m) {
super(null); title = t; maxPrice = p; manager = m; }
public void action() { switch (step) {
case 0:
// Send the cfp to all sellers
ACLMessage cfp = new ACLMessage(ACLMessage.CFP);
for (int i = 0; i < sellerAgents.length; ++i) { cfp.addReceiver(sellerAgents[i]); } cfp.setContent(title); cfp.setConversationId("book-trade"); cfp.setReplyWith("cfp"+System.currentTimeMill is()); // Unique value
myAgent.send(cfp);
// Prepare the template to get proposals mt = MessageTemplate.and( MessageTemplate.MatchConversationId("book- trade"), MessageTemplate.MatchInReplyTo(cfp.getReplyWi th())); step = 1; break; case 1:
// Receive all proposals/refusals from seller agents
ACLMessage reply = myAgent.receive(mt); if (reply != null) { // Reply received if (reply.getPerformative() == ACLMessage.PROPOSE) { // This is an offer int price = Integer.parseInt(reply.getContent() );
if (bestSeller == null | | price < bestPrice) {
// This is the best offer at present
bestPrice = price;
bestSeller = reply.getSender();
}
Những đặc điểm cơ bản của JADE 83
repliesCnt++;
if (repliesCnt >= sellerAgents.length) { // We received all replies
step = 2; } } else { block(); } break; case 2:
if (bestSeller != null && bestPrice <= maxPrice) { // Send the purchase order to the seller that provided the
best offer
ACLMessage order = new
ACLMessage(ACLMessage.ACCEPT_PROPOSAL); order.addReceiver(bestSeller); order.setContent(title); order.setConversationId("book-trade"); order.setReplyWith("order"+System.currentTime Millis()); myAgent.send(order);
// Prepare the template to get the purchase order reply mt = MessageTemplate.and( MessageTemplate.MatchConversationId("book- trade"), MessageTemplate.MatchInReplyTo (order.getReplyWith())); step = 3; } else {
// If we received no acceptable proposals, terminate
step = 4; }
break; case 3:
// Receive the purchase order reply reply = myAgent.receive(mt);
if (reply != null) {
// Purchase order reply received if (reply.getPerformative() == ACLMessage.INFORM) {
// Purchase successful. We can terminate
Những đặc điểm cơ bản của JADE 84
myGui.notifyUser("Book "+title+" successfully purchased.Price = " +
manager.stop(); } step = 4; } else { block(); } break; } }
public boolean done() { return step == 4; }
} // End of inner class BookNegotiator
Các hội thoại phức tạp thường được thực hiện dựa theo một giao thức được xác định rõ ràng, chẳng hạn như những gì được xác định bởi FIPA. Jade cung cấp hỗ trợ phong phú cho một số các giao thức tương tác được sử dụng phổ biến nhất trong gói jade.proto. Cuộc hội thoại mà chúng ta thực hiện ở trên, ví dụ, theo giao thức 'Contract-net' giao thức mà có thể là rất dễ dàng thực hiện bằng cách khai thác lớp jade.proto.ContractNetInitiator. Điều này sẽ tiếp tục được mô tả trong các phần sau.