Java 无法接收mqtt paho上订阅主题的已发布消息

Java 无法接收mqtt paho上订阅主题的已发布消息,java,mqtt,paho,Java,Mqtt,Paho,我正在使用paho发送和接收mqtt消息。到目前为止,发送消息没有问题。我在接收时遇到问题。我的代码是: package BenchMQTT; import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; import org.eclipse.paho.client.mqttv3.IMqttToken; import org.eclipse.paho.client.mqttv3.MqttCallbac

我正在使用paho发送和接收mqtt消息。到目前为止,发送消息没有问题。我在接收时遇到问题。我的代码是:

     package BenchMQTT;

     import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
     import org.eclipse.paho.client.mqttv3.IMqttToken;
     import org.eclipse.paho.client.mqttv3.MqttCallback;
     import org.eclipse.paho.client.mqttv3.MqttException;
     import org.eclipse.paho.client.mqttv3.MqttMessage;
     import org.eclipse.paho.client.mqttv3.MqttClient;

     public class Test_A_2 implements MqttCallback {

     MqttClient clientR;
     MqttClient clientS;

     public Test_A_2() {
     }

     public static void main(String[] args) throws InterruptedException {
         long startTime = System.currentTimeMillis();
         new Test_A_2().doDemo();
         long endTime = System.currentTimeMillis();
     }

    public void doDemo() throws InterruptedException {
    try {   
    clientS = new MqttClient("tcp://mybroker:1883", "Sender");
    clientR = new MqttClient("tcp://mybroker:1883", "Reiever");
    clientR.connect();
    clientS.connect();
    MqttMessage message = new MqttMessage();

    String messagePayload = "qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjk"
            + "lzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghj"
            + "klzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfgh"
            + "jklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfg"
            + "hjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasd"
            + "fghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopas"
            + "dfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopa"
            + "sdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiop"
            + "asdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuio"
            + "pasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyui"
            + "opasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyu"
            + "iopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwerty"
            + "uiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwert"
            + "nmqwertyuiop";

    clientR.subscribe("BenchMQTT");   
    clientR.setCallback(this);

    for(int i=0;i<10;i++)
    {
    message.setPayload((messagePayload)
            .getBytes());
    System.out.println(i);
    clientS.publish("BenchMQTT", message);
    }
    clientR.disconnect();   
    clientS.disconnect();
    clientR.close();   
    clientS.close();

   } catch (MqttException e)
    {
     System.out.println("ERROR");
    }
 }

     @Override
     public void connectionLost(Throwable cause) {
         // TODO Auto-generated method stub

     }

     @Override
     public void messageArrived(String topic, MqttMessage message)
     {
         System.out.println("Received: " + message.toString());
     }

     @Override
     public void deliveryComplete(IMqttDeliveryToken token) {

     }

     }
我想发送消息,然后再接收它们。有什么帮助吗? 预期产出:

0
1
2
3
4
5
6
7
8
9
Received: 0
Received: 1
Received: 2
Received: 3
Received: 4
Received: 5
Received: 6
Received: 7
Received: 8
Received: 9
这不是MQTT(或任何发布/订阅消息)的工作方式,如果接收器连接到服务器,则消息将在发送时传递

例外情况是,如果接收方连接并订阅QOS大于0的主题,然后断开连接并稍后重新连接(未设置clean session标志),则QOS大于0的已发布的丢失消息将在重新连接点传递


另一种可能性是,如果消息是在保留标志设置为true的情况下发布的,那么只有发布到主题的最后一条消息才会在接收客户端订阅的点处传递。

下面的代码做了您想要的,但它强制MQTT以不应该的方式进行操作。上的消息队列仅用于确保将所有消息传递给客户端,即使客户端断开连接一段时间,消息也将始终在尽可能早的时间传递

 import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
 import org.eclipse.paho.client.mqttv3.IMqttToken;
 import org.eclipse.paho.client.mqttv3.MqttCallback;
 import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
 import org.eclipse.paho.client.mqttv3.MqttException;
 import org.eclipse.paho.client.mqttv3.MqttMessage;
 import org.eclipse.paho.client.mqttv3.MqttClient;

 public class Test_A_2 implements MqttCallback {

 MqttClient clientR;
 MqttClient clientS;

 public Test_A_2() {
 }

 public static void main(String[] args) throws InterruptedException {
     long startTime = System.currentTimeMillis();
     new Test_A_2().doDemo();
     long endTime = System.currentTimeMillis();
 }

public void doDemo() throws InterruptedException {
try {   

    MqttConnectOptions options = new MqttConnectOptions();
    options.setCleanSession(false);

clientS = new MqttClient("tcp://localhost:1883", "Sender");
clientR = new MqttClient("tcp://localhost:1883", "Reiever");
clientR.connect(options);
clientS.connect();
clientR.setCallback(this);
clientR.subscribe("BenchMQTT",2);
MqttMessage message = new MqttMessage();

String messagePayload = "qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjk"
        + "lzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghj"
        + "klzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfgh"
        + "jklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfg"
        + "hjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasd"
        + "fghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopas"
        + "dfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopa"
        + "sdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiop"
        + "asdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuio"
        + "pasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyui"
        + "opasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyu"
        + "iopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwerty"
        + "uiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwert"
        + "nmqwertyuiop";

clientR.disconnect();

for(int i=0;i<10;i++)
{
message.setPayload((messagePayload)
        .getBytes());
System.out.println(i);
message.setQos(2);
clientS.publish("BenchMQTT", message);
}



clientR.connect(options);
clientR.setCallback(this);
clientR.subscribe("BenchMQTT",2);

clientR.disconnect();   
clientS.disconnect();
clientR.close();   
clientS.close();

} catch (MqttException e)
{
 System.out.println("ERROR");
 e.printStackTrace();
}
}

 @Override
 public void connectionLost(Throwable cause) {
     // TODO Auto-generated method stub

 }

 @Override
 public void messageArrived(String topic, MqttMessage message)
 {
     System.out.println("Received: " + message.toString());
 }

 @Override
 public void deliveryComplete(IMqttDeliveryToken token) {

 }

 }
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
导入org.eclipse.paho.client.mqttv3.imqttoken;
导入org.eclipse.paho.client.mqttv3.MqttCallback;
导入org.eclipse.paho.client.mqttv3.MqttConnectOptions;
导入org.eclipse.paho.client.mqttv3.MqttException;
导入org.eclipse.paho.client.mqttv3.MqttMessage;
导入org.eclipse.paho.client.mqttv3.MqttClient;
公共类测试_A_2实现MqttCallback{
mqttclientr;
MqttClient客户端;
公共测试_A_2(){
}
公共静态void main(字符串[]args)引发InterruptedException{
long startTime=System.currentTimeMillis();
新测试_A_2().doDemo();
long-endTime=System.currentTimeMillis();
}
public void doDemo()抛出InterruptedException{
试试{
MqttConnectOptions=new MqttConnectOptions();
options.setCleansion(false);
客户端=新的MqttClient(“tcp://localhost:1883“,”发送方“);
clientR=新的MqttClient(“tcp://localhost:1883“,“Reiever”);
clientR.connect(选项);
clientS.connect();
clientR.setCallback(this);
客户认购(“BenchMQTT”,2);
MqttMessage=新MqttMessage();
String messagePayload=“QWERTYUIOPASDFHJKLZXCVBNMQWERTYUIOPASDFHJK”
+“LZxCVBNMqWERTYUIOPASDFGHJKLZxCVBNMqWERTYUIOPASDFHJ”
+“KLZXCVBNMqWERTYUIOPASDFHJKLZXCVBNMqWERTYUIOPASDFGH”
+“jklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfg”
+“HJKLZXCVBNMQWERTYUIOPASDfGJKLZXCVBNMQWERTYUIOPASD”
+“FGHJKLZXCVBNMQWERTYUIOPAS FGHJKLZXCVBNMQWERTYUIOPAS”
+“DFGHJKLZXCVBNMQWERTYUIOPASDFHJKLZXCVBNMQWERTYUIOPA”
+“SDFGHJKLZXCVBNMQWERTYUIOP SDFGHJKLZXCVBNMQWERTYUIOP”
+“ASDFGHJKLZxCVBNMqWERTYUIOPASDFHJKLZxCVBNMqWERTYUIO”
+“PASDFGHJKLZxCVBNMQWERTYUIOPASDFHJKLZxCVBNMQWERTYUI”
+“OPASDfGhjklzxCvNmqwertyuiOPASDfGhjklzxCvNmqwertyu”
+“iopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwerty”
+“UIOPASDfGhjklzxCvNmqwertyUIOPASDfGhjklzxCvNmqwert”
+“nmqwertyuiop”;
clientR.disconnect();

对于(int i=0;在代理端,我有10条消息等待发送给某个订阅者。没有办法接收它们?我只使用paho mqtt客户端就有这个问题。对于其他客户端,以后接收消息没有问题。是否有可能出现这种情况?情况:发送者发送消息,在所有消息发送给接收者之后将订阅和接收邮件。在您编写的代码中,接收客户端在使用发布客户端发送邮件之前订阅主题。如果在for循环之后移动订阅,则可能更接近所需内容。更改:for(int i=0;iHaving再次研究了这个问题,它永远不会像您所描述的那样工作。MQTT代理不会对消息进行排队,除非已经有一个比QOS2更好的断开连接的客户端订阅。(我还编辑了原始答案,以涵盖保留的消息情况)因此,正如您所说,我应该首先使用QOS2连接并订阅它。在断开连接之后。使用发送方发送消息。在发送消息时,我将以以下方式与接收方连接:MqttConnectOptions=new MqttConnectOptions();options.SetCleansion(false);clientR.connect(options);之后,接收方将调用setCallBack我说得对吗?我一步一步地试了,但还是不起作用。
 import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
 import org.eclipse.paho.client.mqttv3.IMqttToken;
 import org.eclipse.paho.client.mqttv3.MqttCallback;
 import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
 import org.eclipse.paho.client.mqttv3.MqttException;
 import org.eclipse.paho.client.mqttv3.MqttMessage;
 import org.eclipse.paho.client.mqttv3.MqttClient;

 public class Test_A_2 implements MqttCallback {

 MqttClient clientR;
 MqttClient clientS;

 public Test_A_2() {
 }

 public static void main(String[] args) throws InterruptedException {
     long startTime = System.currentTimeMillis();
     new Test_A_2().doDemo();
     long endTime = System.currentTimeMillis();
 }

public void doDemo() throws InterruptedException {
try {   

    MqttConnectOptions options = new MqttConnectOptions();
    options.setCleanSession(false);

clientS = new MqttClient("tcp://localhost:1883", "Sender");
clientR = new MqttClient("tcp://localhost:1883", "Reiever");
clientR.connect(options);
clientS.connect();
clientR.setCallback(this);
clientR.subscribe("BenchMQTT",2);
MqttMessage message = new MqttMessage();

String messagePayload = "qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjk"
        + "lzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghj"
        + "klzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfgh"
        + "jklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfg"
        + "hjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasd"
        + "fghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopas"
        + "dfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopa"
        + "sdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiop"
        + "asdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuio"
        + "pasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyui"
        + "opasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyu"
        + "iopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwerty"
        + "uiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwert"
        + "nmqwertyuiop";

clientR.disconnect();

for(int i=0;i<10;i++)
{
message.setPayload((messagePayload)
        .getBytes());
System.out.println(i);
message.setQos(2);
clientS.publish("BenchMQTT", message);
}



clientR.connect(options);
clientR.setCallback(this);
clientR.subscribe("BenchMQTT",2);

clientR.disconnect();   
clientS.disconnect();
clientR.close();   
clientS.close();

} catch (MqttException e)
{
 System.out.println("ERROR");
 e.printStackTrace();
}
}

 @Override
 public void connectionLost(Throwable cause) {
     // TODO Auto-generated method stub

 }

 @Override
 public void messageArrived(String topic, MqttMessage message)
 {
     System.out.println("Received: " + message.toString());
 }

 @Override
 public void deliveryComplete(IMqttDeliveryToken token) {

 }

 }