JADE agent data communication - java

In my agent program(using jade), I have 5 agents, in which one agent is a coordinator others are device agents. All 4 device agents send a array to coordinator.
I want coordinator to receive all 4 arrays and store them as single array. How can I do it?
I send messages via ACLmessage(strings)

You should send your arrays in the 4 messages with msg.setContentObject((Serializable)yourObject)
At the reception :
do a cast : yourLocalObject=(yourObjectType) msg.getContentObject();
Then globalarray.merge(yourLocalObject)

I suggest using jade.proto.AchieveREInitiator behaviour by the Coordinator. This allows for a simple conversation with multiple responders.
The responders, your 4 device agents will respond with jade.proto.AchieveREResponder behiours.
The code should look alil something like this on the Coordinator side
class CoordinatorRequestService extends AchieveREInitiator
{
String agentName;
String Service;
public CoordinatorRequestService (Agent a, ACLMessage msg,String Service ,String agentLocalID) {
super(a, msg);
// TODO Auto-generated constructor stub
this.agentName=agentLocalID;
this.Service=Service;
}
protected Vector prepareRequests(ACLMessage predefinedRequest)
{
ACLMessage requestmsg=new ACLMessage(ACLMessage.REQUEST);
requestmsg.addreciever(//add your agents here)
requestMsgVector.add(requestmsg);
return requestMsgVector;
}
protected void handleInform(ACLMessage inform)
{
recieveData=inform.extractDataRecieved();
globalarray.append(recieveData)
}
Google to find more examples of Contract net and achieve communication.
Goodluck

Related

Backendless - should i subscribe to a channel from service?

In Backendless, there is a method from which I can subscribe to a channel and listen for incoming messages.
Backendless.Messaging.subscribe(
channelName, //some random name
500, //500 ms interval for polling
new AsyncCallback<List<com.backendless.messaging.Message>>() {
#Override
public void handleResponse(List<com.backendless.messaging.Message> messages) {
System.out.println("message received on your channel");
}
#Override
public void handleFault(BackendlessFault backendlessFault) {
}
},
new AsyncCallback<Subscription>() {
#Override
public void handleResponse(Subscription subscription) {
System.out.println("You subscribed to channel" + subscription.getChannelName() + " succssesfuly");
}
#Override
public void handleFault(BackendlessFault backendlessFault) {
System.out.println("Error: " + backendlessFault.getMessage());
}
}
);
If it subscribes from the MainActivity, and data was sent while the app is in another Activity, how can it grab the data from the response (the List in the first handleResponse method) and use it in other activities?
Should I use a service? Should I bind activities to this service with the listener?
Or is there any less complicated way to accomplish my need?
In the very near future i want this listener to work when the app is in the background and show a notification to a user.
Backendless uses two types of Messaging, see Publish-Subscribe Messaging & Push Notifications. The first one is implemented using the listener you used above. The second one uses a service. please refer to the docs, although they are not very good at all they do provide the necessary information.

Server-Sent Events using Play 2 Java

I'm trying to implement Server-sent events in the Play 2 framework (version 2.3.9) using Java. I'd like for an event to be sent to the client every time a "Message" entity is saved to the database. The entity should be sent to the client in Json format.
Message message = new Message();
//some code to populate bean here
message.save(); //save to db
//What do I do with message here?
I was thinking of making a service class that will send events.
public class SSEService {
public static void sendEvent(String data, String id, String name){
EventSource eventSource = new EventSource() {
#Override
public void onConnected() {
//no idea what to do here
}
};
EventSource.Event event = new EventSource.Event(data, id, name);
eventSource.send(event);
}
}
I would then call SSEService.sendEvent() after saving the message. Am I on the right track? What does data, id, and name correspond to in the Event constructor?
Can someone provide a good example in Java 7?

Best way to store messages (native + app2app)

I want to develop a messaging app which will show messages from native content provider (sms uri ) and messages that has been sent from my app.
I am stuck while managing this messages.I have tried below idea but plese do suggest which is the best .
Here is the observer code I have used:
public class MyObserver extends ContentObserver {
public MyObserver(Handler handler) {
super(handler);
}
#Override
public void onChange(boolean selfChange) {
Log.e("uri","change");
this.onChange(selfChange, null);
}
#Override
public void onChange(boolean selfChange, Uri uri) {
// do s.th.
// depending on the handler you might be on the UI
// thread, so be cautious!
Log.e("uri",""+uri.toString());
}
}
Uri uri = Uri.parse("content://sms/");
getContentResolver().registerContentObserver(uri,true,new MyObserver(new Handler()));
1.I have saved all native and A2A messages in databases so it was easy to show but I got problem while synching native message gets delete as there is not broadcast listener for message deletion.
2.Second option is two save only a2a message in database but it is complex to and time consuming to get messages from two different places (database and content provider and manage the to show view like inbox)
3.Third is to save all app to app messages in content provider with custom message type.and show all messages from content provider only .
Please guide me on this.

JADE ContractNet and GUI problems

I have some problems with use of ContractNet (Interaction Protocol) and GUI with the use of JADE multiagent framework.
In particular, in the override of handlePropose method.
I know that my problem comes from the use of a GUI. Let me explain:
My agent (Initiator) uses a first GUI and, after a click, the
conversation begins with a second agent (Responder). According to the
Protocol, the Initiator has thus sent a CFP to Responder. The agent
Responder responds with a PROPOSE that contains different data.
Since here, everything ok. Now...
I wish that the agent Initiator, BEFORE returning a reply, may examine
the data ... ie publish them on a JTable, for the user! The user will
examine the proposal via GUI and will choose if to accept or not, by
click on a button.
If accept, the Initiator send ACCEPT_PROPOSAL.
If not accept, the Initiator send REJECT_PROPOSAL.
This should be done in the method handleProposal. This is my code:
#Override
protected void handlePropose(final ACLMessage propose, final Vector acceptances) {
try {
System.out.println("Agent "+getLocalName()
+": receive PROPOSE from "+propose.getSender().getLocalName());
final ACLMessage reply = propose.createReply();
Vector<Goods> goods = (Vector<Goods>) propose.getContentObject();
// the JTable's GUI for visualize the list of data:
final GoodsChoiceBox gcb = new GoodsChoiceBox(propose.getSender().getName(), goods);
// the problem:
gcb.getExecuteJButton().addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
reply.setPerformative(ACLMessage.ACCEPT_PROPOSAL);
System.out.println("Agent "+getLocalName()+": send ACCEPT PROPOSAL ");
acceptances.addElement(reply);
}
});
// similar case, but for REJECT:
// gcb.getAbortJButton().addActionListener(... bla bla
gcb.setVisible(true);
} catch (UnreadableException e){
e.printStackTrace();
}
}
..... But, obviously, does not work.
In the Initiator agent, the ContractNet behaviour is aborted... so also handleInform, handleRefuse and handleFailure (for handle the answers) do not work.
The Initiator's principal GUI is blocked. And other problems...
Instead, if I do this (WITHOUT JButton, another GUI and ActionListener):
#Override
protected void handlePropose(final ACLMessage propose, final Vector acceptances) {
try {
System.out.println("Agent "+getLocalName()
+": received PROPOSE from "+propose.getSender().getLocalName());
final ACLMessage reply = propose.createReply();
Vector<Goods> goods = (Vector<Goods>) propose.getContentObject();
// the JTable's GUI for visualize the list of data:
final GoodsChoiceBox gcb = new GoodsChoiceBox(propose.getSender().getName(), goods);
reply.setPerformative(ACLMessage.ACCEPT_PROPOSAL);
System.out.println("Agente "+getLocalName()+": ACCEPT PROPOSAL di "+propose.getSender().getLocalName());
acceptances.addElement(reply);
} catch (UnreadableException e){
e.printStackTrace();
}
}
.... works.
I know that the problem is the ActionListener and its multithread nature.
But I need the GUI there.
How can I fix?
I try to answer myself. I'm not sure it's the best solution, but certainly works.
Note that before coming to this solution I am well documented with the guides and tutorials found (on http://jade.tilab.com/), and confronting myself with other
JADE developers (in mailing lists http://jade.tilab.com/pipermail/jade-develop/)
The answer is complicated, so I'll try to be exhaustive.
In my project I have to deal with two different types of agents.
The ShipperAgent, which represents one shipper: it keeps track of the vehicles owned by the shipper, those available, and the goods "reserved" from it.
The BuyerAgent, which represents customers (or buyers): each customer has a list of goods that want to move from point A to point B.
The two agents are registered to the yellow pages service.
In ShipperAgent, clicking on the "SEARCH" button you start a search: start a Contract Net Interaction Protocol.
Explain the Contract Net Interaction Protocol and my case
In the standard FIPA: http://www.fipa.org/specs/fipa00029/SC00029H.html
In JADE guide can be found here: http://jade.tilab.com/doc/programmersguide.pdf (p. 35)
Further on you will notice the changes that I had to take.
The ShipperAgent sends CFP each BuyerAgent.
Each BuyerAgent:
2.1 if he has goods, send a PROPOSE to ShipperAgent.
2.2 if does not have the goods, send a REFUSE to ShipperAgent. And for buyer, the protocol ends.
Since here is easy. With the sniffer, we can observe:
Now:
The ShipperAgent:
3.1 receives one or more PROPOSE by buyers, and displays (see image below).
3.2 if it receives the REFUSE (or does not receive anything after a certain time), ending communication with those buyer.
Here's how the Shipper graphically displays the proposals:
Now it's up to the user to choose which goods wants and what not.
To achieve this, I had to create some kind of "internal communication" to the agent himself: the GUI (in 3.1), once clicked Execute, sends a message to the agent. It may seem inelegant, but it seems to be the only way to not crash the protocol side ShipperAgent.
The ShipperAgent:
 4.1 if the user has selected one or more goods proposals (and click Execute), sends to the corresponding BuyerAgent an ACCEPT_PROPOSAL, where specific goods that want to (a subset of the previous proposal).
 4.2 if the user does not select any good (or click on Cancel), sends to the corresponding BuyerAgent an REJECT_PROPOSAL. Ends communication to that buyer.
The BuyerAgent:
 5.1 if receives an ACCEPT_PROPOSAL, check that the goods are still available (any other shippers could have them "reserved" in the meanwhile) and, if so, sends an INFORM.
5.2 if receives an ACCEPT_PROPOSAL ma one or more goods are no longer available, sends FAILURE.
 5.3 if it receives an REJECT_PROPOSAL, ends communication with the ShipperAgent.
In brief this (for example):
The code
BuyerAgent.java
I create a dispatcher who is always ready to receive the CFP. As soon as it receives and start protocol, buyer-side: start SearchJobResponder.
/*
* ...
*/
final MessageTemplate template = MessageTemplate.and(
MessageTemplate.MatchProtocol(FIPANames.InteractionProtocol.FIPA_CONTRACT_NET),
MessageTemplate.MatchPerformative(ACLMessage.CFP) );
// SSResponderDispatcher:
SSResponderDispatcher dispatcher = new SSResponderDispatcher(this, template) {
BuyerAgent b = (BuyerAgent) this.myAgent;
protected Behaviour createResponder(ACLMessage initiationMsg) {
// SearchJobResponder for single cfp:
return new SearchJobResponder(b, initiationMsg);
}
};
addBehaviour(dispatcher);
/*
* ...
*/
ShipperAgent.java
Search all buyer, creates a CFP and start the protocol, shipper-side: start SearchJobInitiator.
/*
* ...
*/
ACLMessage cfp = new ACLMessage(ACLMessage.CFP);
AID[] buyerAgents = searchBuyers(); // search all buyerAgents
for (AID buyer : buyerAgents)
cfp.addReceiver(buyer);
addBehaviour(new SearchJobInitiator(this, cfp));
/*
* ...
*/
SearchJobInitiator.java
This was the hard part...
/*
* ...
*/
public class SearchJobInitiator extends ContractNetInitiator {
ShipperAgent shipperAgent;
public SearchJobInitiator(ShipperAgent a, ACLMessage cfp) {
super(a, cfp);
shipperAgent=a;
// Very important:
registerHandleAllResponses(new HandleProposes());
}
#Override
protected Vector<?> prepareCfps(ACLMessage cfp) {
long now = System.currentTimeMillis();
cfp.setConversationId("contractNet-by-"
+shipperAgent.getAID().getLocalName()+now);
cfp.setContent("Fammi delle proposte di lavoro");
/*
* filtering...
*/
cfp.setProtocol(FIPANames.InteractionProtocol.FIPA_CONTRACT_NET);
cfp.setReplyByDate(new Date(now+10000));
//cfp.setReplyWith("cfp"+System.currentTimeMillis()) //useless, is overwrited at the end
return super.prepareCfps(cfp);
}
//inner class for handling a single proposal
public class HandleProposes extends Behaviour {
private static final long serialVersionUID = 1L;
private Vector<ACLMessage> proposes;
private Vector<ACLMessage> acceptances;
private int numberOfProposes;
public void onStart() {
proposes = (Vector<ACLMessage>) getDataStore().get(ALL_RESPONSES_KEY);
acceptances = (Vector<ACLMessage>) getDataStore().get(ALL_ACCEPTANCES_KEY);
numberOfProposes=proposes.size();
for (Iterator I=proposes.iterator(); I.hasNext();) {
ACLMessage propose = (ACLMessage) I.next();
// Very important:
if (propose.getPerformative()==ACLMessage.PROPOSE)
myAgent.addBehaviour(new HandleSinglePropose(propose, acceptances));
else
numberOfProposes--;
}
}
public void action() {
if (!done())
block();
}
public boolean done() {
return (acceptances.size()==numberOfProposes);
}
/*
* Inner class for handle a single proposal and display it:
*/
public class HandleSinglePropose extends Behaviour {
private ACLMessage propose;
private Vector<ACLMessage> acceptances;
private boolean finish=false;
public HandleSinglePropose (ACLMessage propose, Vector<ACLMessage> acceptances) {
this.propose=propose;
this.acceptances=acceptances;
// This is GUI in 3.1 point
GoodsChoiceBox gcb = new GoodsChoiceBox(shipperAgent, this, propose); // fill the JTable
gcb.setVisible(true);
}
#Override
public void action() {
MessageTemplate mt = MessageTemplate.and(
MessageTemplate.MatchSender(shipperAgent.getAID()),
MessageTemplate.and(
MessageTemplate.MatchReplyWith("response"+propose.getReplyWith()),
MessageTemplate.or(
MessageTemplate.MatchPerformative(ACLMessage.ACCEPT_PROPOSAL),
MessageTemplate.MatchPerformative(ACLMessage.REJECT_PROPOSAL)
) ) ) ;
// Read data from GUI. The user accept or reject:
ACLMessage decisionFromGUI = shipperAgent.receive(mt);
if (decisionFromGUI != null) {
ACLMessage reply = propose.createReply();
// bla bla...
finish=true;
HandleProposes.this.restart();
} else {
block();
}
}
public boolean done() {
return finish;
}
public void handleChoice(ACLMessage propose, boolean bool, Vector<Goods> selectedGoods) {
ACLMessage reply;
if (bool){
reply = new ACLMessage(ACLMessage.ACCEPT_PROPOSAL);
//...
} else {
reply = new ACLMessage(ACLMessage.REJECT_PROPOSAL);
//...
}
reply.addReceiver(shipperAgent.getAID());
reply.setReplyWith("response"+propose.getReplyWith());
shipperAgent.send(reply);
}
} // closes HandleSinglePropose
} // closes HandleProposes
}
SearchJobResponder.java
The responder is simple. The only thing of note: I extends SSContractNetResponder, don't extends ContractNetResponder.
public class SearchJobResponder extends SSContractNetResponder {
BuyerAgent buyerAgent;
public SearchJobResponder(BuyerAgent a, ACLMessage cfp) {
super(a, cfp);
buyerAgent = a;
}
/*
* override methods...
*/
}
GoodsChoiceBox.java
The GUI for show the proposals...
public GoodsChoiceBox(final Agent agent, final HandleSinglePropose behaviour, final ACLMessage propose){
/*
* graphics stuff
*/
// if goods selected and press Execute
behaviour.handleChoice(propose,true,selectedGoods);
//else
behaviour.handleChoice(propose,false,null);
/*
* bla bla
*/
}
I know, I have dwelt much, but I did not know how else to explain.
However, now my project work. But I'm open to any suggestions.
I often run into this problems of this sort. These are Finite State machine behaviours so you should be able to pause and resume a behavior but I'm not sure how. What I do is create two separate Interaction behaviors on the initiator side and one on the responder side.
Initiator Responder
| |
| |
| First behaviour |The responder only has 1 behaviour
|| CFP-> ||
|| <-Proposal ||
| ||
| Second behaviour ||
|| Accept prop-> ||
|| <-Response ||
| |
Two points to remember
(1)
Make sure that you save the conversationID
msgRecieved.getConversationID
from the first behaviour and use it in the second Behaviour.
msg.setConversationID().
(2)
The second behavior is another Contract net initiator but in prepareCFPs method set MESSAGE performative to accept proposal
class ContractServiceList extends ContractNetInitiator
{
protected Vector prepareCfps(ACLMessage cfp) {
ACLmessage AP= new ACLmessage(ACLmessage.ACCEPT_PROPOSAL)
.....
These things are hard to explain so I tried to attached a picture but have 2 little rep points.
I now have enough rep points to attach the picture which I am doing.
I just realized that there is another solution to this problem. The second solution involves using ChildBehaviours and data stores. A child behaviour can be initiated pausing the parent behaviour. The parent behaviour must then be resumed one the child is complete.
I'm attaching a pic to better explain this interaction.
So at point A in your CNI (ContractNetInitiator) parent behaviour you want to initiate the Child behaviour. You would do this by using the CNI.registerHandlePropose(new Childbehaviour).
This is what the setup() method should look like:
protected void setup()
{
ContractNetInitiator parentBehave= new ContractNetInitiator (null, null, GlobDataStore);
ContractNetInitiator.registerHandlePropose(new ChildBehavoiur (GlobDataStore));
addBehaviour(CNI);
}
In you Child behaviour you will have to check the data from the parent (GlobDataStore) and return a message to be passed back. Code to follow:
class ChildBehaviour extends OneShotBehaviour{
#Override
public void action() {
//evaluate globalestore here;
ACLMessage CNIresponse=new ACLMessage();
if(true)
{
storeNotification(ACLMessage.ACCEPT_PROPOSAL, CNIresponse);
}
else
{
storeNotification(ACLMessage.REJECT_PROPOSAL, CNIresponse);
}
}
public void storeNotification(int performative, ACLMessage original)
{
// Retrieve the incoming request from the DataStore
String incomingCFPkey = (String) ((ContractNetResponder) parent).CFP_KEY;
incomingCFPkey = (String) ((ContractNetResponder) parent).CFP_KEY;
ACLMessage incomingCFP = (ACLMessage) getDataStore().get(incomingCFPkey);
// Prepare the notification to the request originator and store it in the DataStore
ACLMessage notification = incomingCFP.createReply();
notification.setPerformative(performative);
notification.setContent(original.getContent());
String notificationkey = (String) ((ContractNetResponder) parent).PROPOSE_KEY;
getDataStore().put(notificationkey, notification);
}
}

Send Object from Service to Activity (Can't marshal non-Parcelable)

I'm trying to send data from my activity to a service and receive some information back, but i'm getting:
java.lang.RuntimeException: Can't
marshal non-Parcelable objects across
processes.
The code from activity looks like this:
Message msg = Message.obtain(null, 1);
msg.obj=1;
msg.replyTo=new Messenger(new PlanRequestIncomingHandler());
try {
msgService.send(msg);
} catch (RemoteException e) {
Log.i(tag, "Can not send msg to service");
e.printStackTrace();
}
When I set msg.obj = something I get java.lang.RuntimeException, can somebody help me?
You can pass Parcelable type objects via Messenger. Or else if you want to pass primitive data types use Bundle wrapper as below.
In Service End:
//Create a bundle object and put your data in it
Bundle bundle = new Bundle();
bundle.putInt("key", 1);
Message msg = Message.obtain(null, 123);
msg.obj = bundle;
msg.replyTo = new Messenger(new PlanRequestIncomingHandler());
try {
msgService.send(msg);
} catch (RemoteException e) {
Log.i(tag, "Can't send msg to service");
e.printStackTrace();
}
In Activity End:
switch(msg.what) {
case 123:
if(msg.obj != null) {
Bundle bundle = (Bundle) msg.obj;
System.out.println("Got integer "+ bundle.getInt("key"));
}
break;
}
cheers :-)
Old question, but I am answering so it might help someone in the future.
If you are using actual objects, then by all means, please implement Parcelable
Android: How to implement Parcelable to my objects?
However, as the OP stated that he tried using Primitives and it did not work, this is what to do.
The problem lies here msg.obj=1; This expects an actual object that implements Parcelable
Use msg.arg1 = 1;
you can then retrieve the argument on the service side using msg.arg1
For simplicity I use (straight from my code)
Message msg = Message.obtain(null, PlayerService.MSG_ACTION_SEEK, i, -1);
The -1 is just a holder for me.
Hope this helps.
Edit:
Be careful with
Message msg = Message.obtain(null, PlayerService.MSG_ACTION_SEEK, i);
This signature is equivalent to the OP's first attempt and expects a Parcelable and is what actually tripped me and got me searching in the first place. It won't throw an error until runtime.
Other than primitive data, the objects you're juggling between Activities and Services need to implement Parcelable and preferably Serializable.
I hope this helps,
Best
-serkan
You must use the Bundle to pass the conventional type data, otherwise it will be wrong:
Java.lang.RuntimeException: Can't non-Parcelable objects across marshal processes.
Because the Binder transaction data is called Parcel, the Parcelable interface must be implemented, otherwise it is not possible to communicate between the two applications. The reason why Bundle is passed because the class implements the Parcelable interface. Of course, if you want to pass the class must also implement the interface.
you can write like down:
Message msg = Message.obtain(null, 1);
msg.getData().putInt("key",1);
msg.replyTo=new Messenger(new PlanRequestIncomingHandler());
try {
msgService.send(msg);
} catch (RemoteException e) {
Log.i(tag, "Can not send msg to service");
e.printStackTrace();
}
sorry,my english is very bad
I have implemented Actor Model (like Akka) for Android, since Akka requires Java 8, i made my own implementation for it for Android, using RxJava2 , it was very easy to implement ... And once it is there, you can send messages holding any object to any receiver (Activity, Fragment, Service, Pojo, etc.) without worrying about threads or serialization
It is hard to explain my own implementation in details if you dont know what is Actor Model, but if you do, you can make an interface named "Actor" with one method
void onMessageReceived(Message message);
And you can implement this interface by any Actor you have, and to register any Actor, you can create an ActorSystem class that has methods :
static void register(Actor actor, PublishSubject<Message> mailbox);
static void unregister(Actor actor);
static void send(Message message, Class<? extends Actor> ... actors);
And when you register your Actor (Activity or Service), you decide what is your thread / scheduler to receive your messages on, through :
PublishSubject.observeOn(Schedulers.trampoline());
And you register your Actor in onCreate() and unRegister in onDestroy()
Or if you want a library for that (but i did not test it), you can take a look at this :
https://github.com/actorapp/droidkit-actors

Categories

Resources