Search code examples
javaarraysarraylistpugmqtt

Java arraylist elements update, Jade


Now I want to build an ArrayList MessageQueue, and it will automatically fill in the messages from the MQTT broker. For example, if there are three messages sent from MQTT, then in MessageQueue, there should be automatically three messages. My current code is

import java.util.ArrayList;
import TestMQTT.SubscribeSample;
import jade.core.Agent;
import jade.core.behaviours.TickerBehaviour;
import jade.lang.acl.ACLMessage;

public class ServerAgent extends Agent {

private static final long serialVersionUID = 1L;
protected ArrayList<ACLMessage> MessageQueue = null;
// protected ArrayList<String> myProcess = new ArrayList<>();

public void setup() {
    
    SubscribeSample subscribeSample = new SubscribeSample();
    subscribeSample.subscribe("Json");

    //repeat the following actions every 5 seconds
    this.addBehaviour(new TickerBehaviour(this, 5000) {

        @Override
        protected void onTick() {
            
            if (subscribeSample.getMsg() != null && MessageQueue != null) {
                MessageQueue.add(subscribeSample.getMsg());
                System.out.println("Current MessageQueue is:" + MessageQueue);


            } else {
                System.out.println("No message yet");
            }
            
            System.out.println("The whole MessageQueue are:" + MessageQueue);

        }

The subscribesample class are defined as follows:

public class SubscribeSample {

public static String arrivedMessage;
public static ArrayList<Object> ReceivedRequests = new ArrayList<>();
public static ACLMessage msg = null;


public static void subscribe(String TOPIC) {
    
    String broker = "tcp://192.168.137.100:1883";
    
    int qos = 1;
    String clientid = "mqtt-explorer-3260c410";
    MaintestOutput m = new MaintestOutput();
    
    try {
        
        MqttClient client = new MqttClient(broker, clientid, new MemoryPersistence());
        MqttConnectOptions options = new MqttConnectOptions();
        options.setCleanSession(true);
        options.setConnectionTimeout(10);
        options.setKeepAliveInterval(20);

        client.setCallback(new MqttCallback() {

            public void connectionLost(Throwable cause) {
                System.out.println("connectionLost");
            }

            public void messageArrived(String TOPIC, MqttMessage message)
                    throws ClassNotFoundException, IOException {
                System.out.println("======get message from [" + TOPIC + "]======");
                System.out.println("message content:" + new String(message.getPayload()));

                String Json = new String(message.getPayload());
                Gson gson = new Gson();
                msg = gson.fromJson(Json, ACLMessage.class);

            public void deliveryComplete(IMqttDeliveryToken token) {
                System.out.println("deliveryComplete---------" + token.isComplete());
            }

        
        }

        );

        // estblished connection
        System.out.println("conneted to the broker: " + broker);
        client.connect(options);

        System.out.println("connected successfully");
        client.subscribe(TOPIC, qos);
        System.out.println("start listening" + TOPIC);
    } catch (

    Exception e) {
        e.printStackTrace();
    }
}

In my ServerAgent, System.out.println("Current MessageQueue is:" + MessageQueue) will only show the current received message, not the previours message, and the output of System.out.println("The whole MessageQueue are:" + MessageQueue) is always zero.

I want to achieve that every message the ServerAgent receive, it will automatically be sent to the MessageQueue, the output of System.out.println("The whole MessageQueue are:" + MessageQueue) is the all the messages


Solution

  • The list MessageQueue is always null; you aren't assigning a new list to it.

    Change the declaration to:

    protected ArrayList<ACLMessage> MessageQueue = new ArrayList<>();
    

    Also, better to name it messageQueue in line with Java Naming Conventions that recommends camelCase for fields/variables/parameters.

    Also, always best to use the abstract type, so List<ACLMessage> instead of ArrayList<ACLMessage>.

    Recommended form is:

    protected List<ACLMessage> messageQueue = new ArrayList<>();