MQTT发布-在同一客户机中订阅

MQTT发布-在同一客户机中订阅,mqtt,Mqtt,我的要求如下: 存在多个客户端IoT设备。它们向服务器发送数据,接收来自服务器的消息,并改变其行为。有各种各样的前端希望监视来自设备的数据并向设备发送命令 我阅读了有关MQTT的文章,了解到它中间有订阅者、发布者和代理 我的问题是,我可以将我的设备注册为同一个代理的发布者和订阅者吗?这样做明智吗?谢谢。我看这没什么问题 为了使事情保持独立,您可能需要使用不同的通道来传输数据和控制消息。整个设置中应该只有一个代理。出于可伸缩性的原因,我们可以放置多个代理,这些代理可以协同工作,并且作为一个整体,始

我的要求如下:

存在多个客户端IoT设备。它们向服务器发送数据,接收来自服务器的消息,并改变其行为。有各种各样的前端希望监视来自设备的数据并向设备发送命令

我阅读了有关MQTT的文章,了解到它中间有订阅者、发布者和代理


我的问题是,我可以将我的设备注册为同一个代理的发布者和订阅者吗?这样做明智吗?谢谢。

我看这没什么问题


为了使事情保持独立,您可能需要使用不同的通道来传输数据和控制消息。

整个设置中应该只有一个代理。出于可伸缩性的原因,我们可以放置多个代理,这些代理可以协同工作,并且作为一个整体,始终是单个代理的表示。在多代理设置中,边缘客户端将仅连接到单个代理

确保为每个设备保留一个唯一的发布主题和一个唯一的订阅主题,以实现设备的可扩展性、较低的边缘处理和易于理解人类

同样,基于用例总是存在权衡

干杯,
Ranjith

是的,在同一个客户端中发布和订阅MQTT应该没有问题

以下是MQTT客户机的示例Java代码,该客户机同时具有发布和订阅功能:

import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class MQTTClient {

    private static final Logger logger = LoggerFactory.getLogger(MQTTClient.class);

    public static void main(String[] args) {
        MqttClient mqttClient;
        String tmpDir = System.getProperty("java.io.tmpdir");
        String subscribeTopicName = "echo";
        String publishTopicName = "thing";
        String payload;
        MqttDefaultFilePersistence dataStore = new MqttDefaultFilePersistence(tmpDir);
        try {
            mqttClient = new MqttClient("tcp://localhost:1883", "thing1", dataStore);
            MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
            mqttConnectOptions.setUserName("/:guest");
            mqttConnectOptions.setPassword("guest".toCharArray());
            mqttConnectOptions.setCleanSession(false);
            mqttClient.connect(mqttConnectOptions);
            logger.info("Connected to Broker");
            mqttClient.subscribe(subscribeTopicName);
            logger.info(mqttClient.getClientId() + " subscribed to topic: {}", subscribeTopicName);
            mqttClient.setCallback(new MqttCallback() {
                @Override
                public void connectionLost(Throwable throwable) {
                    logger.info("Connection lost to MQTT Broker");
                }

                @Override
                public void messageArrived(String topic, MqttMessage message) throws Exception {
                    logger.info("-------------------------------------------------");
                    logger.info("| Received ");
                    logger.info("| Topic: {}", topic);
                    logger.info("| Message: {}", new String(message.getPayload()));
                    logger.info("| QoS: {}", message.getQos());
                    logger.info("-------------------------------------------------");

                }

                @Override
                public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
                    logger.info("Delivery Complete");
                }
            });
            MqttMessage message = new MqttMessage();
            for (int i = 1; i < 6; i++) {
                payload = "Message " + i + " from Thing";
                message.setPayload(payload
                        .getBytes());
                logger.info("Set Payload: {}", payload);
                logger.info(mqttClient.getClientId() + " published to topic: {}", publishTopicName);
                //Qos 1
                mqttClient.publish(publishTopicName, message);
            }
        } catch (MqttException me) {
            logger.error("reason: {}", me.getReasonCode());
            logger.error("msg: {}", me.getMessage());
            logger.error("loc: {} ", me.getLocalizedMessage());
            logger.error("cause: {}", me.getCause());
            logger.error("excep: {}", me);
            me.printStackTrace();
        }
    }
}
import org.eclipse.paho.client.mqttv3.*;
导入org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence;
导入org.slf4j.Logger;
导入org.slf4j.LoggerFactory;
公共类MQTTClient{
私有静态最终记录器Logger=LoggerFactory.getLogger(MQTTClient.class);
公共静态void main(字符串[]args){
MqttClient MqttClient;
字符串tmpDir=System.getProperty(“java.io.tmpDir”);
字符串subscribeTopicName=“echo”;
字符串publishTopicName=“thing”;
管柱有效载荷;
MqttDefaultFilePersistence数据存储=新的MqttDefaultFilePersistence(tmpDir);
试一试{
mqttClient=新mqttClient(“tcp://localhost:1883“,”thing1“,数据存储);
MqttConnectOptions MqttConnectOptions=新MqttConnectOptions();
mqttConnectOptions.setUserName(“/:guest”);
mqttConnectOptions.setPassword(“guest.tocharray());
mqttConnectOptions.setCleanSession(false);
连接(mqttConnectOptions);
logger.info(“连接到经纪人”);
mqttClient.subscribe(subscribeTopicName);
info(mqttClient.getClientId()+“订阅主题:{}”,subscribeTopicName);
setCallback(新的MqttCallback(){
@凌驾
public void connectionLost(可丢弃可丢弃){
info(“与MQTT代理的连接丢失”);
}
@凌驾
public void messageArrived(字符串主题,MqttMessage消息)引发异常{
logger.info(“-------------------------------------------------------------”;
记录器信息(“已收到”);
logger.info(“|主题:{}”,主题);
logger.info(“| Message:{}”,新字符串(Message.getPayload());
logger.info(“|QoS:{}”,message.getQos());
logger.info(“-------------------------------------------------------------”;
}
@凌驾
公共无效交付完成(IMqttDeliveryToken IMqttDeliveryToken){
logger.info(“交付完成”);
}
});
MqttMessage=新MqttMessage();
对于(int i=1;i<6;i++){
payload=“消息”+i+“来自对象”;
message.setPayload(有效载荷
.getBytes());
info(“设置有效载荷:{}”,有效载荷);
info(mqttClient.getClientId()+“发布到主题:{}”,publishTopicName);
//Qos 1
mqttClient.publish(publishTopicName,消息);
}
}捕获(MqttException me){
logger.error(“原因:{}”,me.getReasonCode());
logger.error(“msg:{}”,me.getMessage());
logger.error(“loc:{}”,me.getLocalizedMessage());
logger.error(“原因:{}”,me.getCause());
logger.error(“excep:{}”,me);
me.printStackTrace();
}
}
}
在上面的代码中,请选中mqttClient.subscribe进行订阅,选中mqttClient.publish进行发布。
我在博客中解释了如何使用RabbitMQ作为MQTT代理端到端地工作,我使用的示例工作代码在GitHub上可用。请检查:

作为一个物联网设备,它可能有间歇性连接,因此需要有某种本地代理或缓存来存储设备脱机时的消息。当你需要运行本地代理(或网关)和将所有本地设备连接到本地代理(即使没有互联网也可以工作)时,你有什么想法可以处理吗?@RomanGaufman。代理将收集和存储数据并将其发送到中央服务器。另一方面,如果每个位置的设备数量较少,则可以在客户机本身中使用缓存机制。