Java通过MQTT协议对接第三方设备————够用但不详细

1. MQTT协议、参数需要注意这些!

1.1 详细介绍

其他地方很多,不多说了,遗步看风景这个老哥写的很清楚!

MQTT协议详解(完整版)-CSDN博客

1.2 参数介绍

IP:协议中broker的IP地址,端口一般是1883,具体看配置;

username:在部署broker时会配置username和password,如果broker是你们部署的,你应该清楚;如果是第三方的就直接找他要;

password:同上;

QoS:QoS 0至多一次、QoS 1至少一次、QoS 2只有一次(上边文章解释的比较清楚、自己看一下);

clientId:这个东西自己看着设置就好了,我的理解是连接同一个broker的唯一标识。所以在一个broker中这个一定是唯一的,不要和其他客户端的一样!有相同的两个clientId连接同一个broker会导致连接断开哟!

topic:主题,如果broker是学校,topic就是班级;你可以通过订阅topic获取到其他客户端下发的消息,相反的其他客户端也可以获取到你在某一个topic下发的消息;

主要的就这些了!

2. 业务场景

        说一下我的业务场景,我需要通过MQTT协议获取门禁设备的人员进出记录,设备方需要我先下发我们的人员信息,然后根据我下发的人员信息回复相应人员的进出记录;我再把这些进出记录保存到本地数据库;像这样↓

        我向topic1发布人员信息,设备订阅topic1获取我下发的人员信息,然后在收到人员信息后,设备向topic2发送该人员的出入记录,我通过订阅topic2获取设备发送的消息,然后处理保存。

3. Java后端操作流程

3.1 Maven依赖

第一步肯定是先搞依赖了!

        <dependency>
            <groupId>org.eclipse.paho</groupId>
            <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
            <version>1.2.2</version>
        </dependency>

(broker如果需要自己部署的话,看4)

3.2 与broker建立连接

        这里搜到了很多方法,刚开始写的类似于这位老哥的java连接MQTT服务器(Springboot整合MQTT)_mqtt java-CSDN博客

这样写也没毛病,但是总要setMqttClient(),嫌麻烦,遂改!如下↓:

        直接在项目模块启动时初始化一个连接(IP、username、password最好写在配置文件哈,我这是方便展示这么写的);

@Configuration
@Slf4j
public class MQTTClientConfig {
​
    /**
     * 创建并配置一个MqttClient实例。
     * 该实例用于与MQTT服务器建立连接,并设置相应的连接选项,如自动重连、会话超时等。
     * 
     * @return MqttClient 返回配置好的MqttClient实例。
     */
    @Bean
    public MqttClient mqttClient() {
        MemoryPersistence dataStore = new MemoryPersistence();
        String serverUrl = "tcp://ip:1883";
        //前边有提到过,连接同一个broker的clientId是唯一的,我这么做是因为我们项目分测试和正式环境,正式环境是直接拉测试环境的docker,不这么搞会一直重连,如果你只有一个环境再跑就不用UUID,自己起个名就好了。
        String clientId = "mqtt"+ UUID.randomUUID();
        MqttClient client = null;
        try {
        // 初始化MqttClient实例
        client = new MqttClient(serverUrl, clientId, dataStore);
        
        // 配置连接选项
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setPassword("username".toCharArray());
        mqttConnectOptions.setUserName("password");
        mqttConnectOptions.setAutomaticReconnect(true); // 设置自动重连
        mqttConnectOptions.setCleanSession(false); // 设置会话不被清除,保持连接状态
        mqttConnectOptions.setConnectionTimeout(10); // 设置连接超时时间
        mqttConnectOptions.setKeepAliveInterval(60); // 设置会话心跳时间
        
        // 建立连接并设置回调
        client.connect(mqttConnectOptions);
        client.setCallback(new Callback());
    } catch (MqttException e) {
        e.printStackTrace();
        log.info(e.getMessage());
    }
    
    return client;
}

接下来是回调函数,有很多老哥都是直接操作的数据库存入数据库的,我这里是直接存入redis了,有两个原因:

  1. 在这里如果要操作数据库,只用用@Autowired注解注入是不行的,使用xxxService或者xxxMapper的方法都要在这里边初始化然后再引用,处理数据的话我还会用到ObjectMapper,也要搞,太麻烦,遂存入redis,去别的地方拿出来存入数据库;

  2. 业务场景问题:前边提到过我要先下发,设备才会给我相应的信息,我这里有几百个人员信息,也不能一次只发一条,所以一次性全发过去(用的队列,隔一定时间发,设备消费不及时也是会丢数据的),再依次接收,避免消息丢失;

    不需要用redis的话就把service或者mapper直接照这个内部类搞一下,用到什么方法写什么方法就好了;如果你也要用redis记得用完收拾一下;

@Slf4j
@Component
public class Callback implements MqttCallback {
​
    @Component
    public static class RedisTemplateOperate{
        @Autowired
        private RedisTemplate redisTemplate;
        private static RedisTemplateOperate redisTemplateOperate;
        @PostConstruct
        public void init() {
            redisTemplateOperate = this;
            redisTemplateOperate.redisTemplate = this.redisTemplate;
        }
​
        public void set(String key, Object value) {
            redisTemplateOperate.redisTemplate.opsForList().rightPush(key, value);
        }
​
        public void expire(String key, long value,TimeUnit timeUnit){
            redisTemplateOperate.redisTemplate.expire(key,value,timeUnit);
        }
​
    }
​
​
    /**
     * MQTT 断开连接会执行此方法
     */
    @Override
    public void connectionLost(Throwable throwable) {
        log.info("MQTT连接断开 :{}", throwable.getMessage());
    }
​
    /**
     * publish发布成功后会执行到这里
     */
    @Override
    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
        log.info("发布消息成功");
    }
​
    /**
     * subscribe订阅后得到的消息会执行到这里
     */
    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        try {
            log.info("收到来自 " + topic + " 的消息:{}", new String(message.getPayload()));
            String payloadString = new String(message.getPayload(), StandardCharsets.UTF_8);
            
            RedisTemplateOperate.redisTemplateOperate.set(key,new String(message.getPayload()));
            log.info("考勤信息存入redis");
​
        }catch (Exception e){
            e.printStackTrace();
            log.error("消息处理失败",e);
        }
​
    }
​
}

然后是监听器,没什么说的就监听你接收数据的topic就好了;

@Slf4j
@Component
public class MQTTListener implements ApplicationListener<ContextRefreshedEvent> {
    @Resource
    private MqttClient mqttClient;
​
    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        try {
            //订阅topic
            mqttClient.subscribe(MQTTEnum.MQTT_SUB_TOPIC_ONE.getValue(),0);
            mqttClient.subscribe(MQTTEnum.MQTT_SUB_TOPIC_TWO.getValue(),0);
            mqttClient.subscribe(MQTTEnum.MQTT_SUB_TOPIC_THREE.getValue(),0);
            mqttClient.subscribe(MQTTEnum.MQTT_SUB_TOPIC_FOUR.getValue(),0);
        } catch (MqttException e) {
            log.error(e.getMessage(), e);
        }
    }
}

然后、跑起来测试一下:这个软件可以MQTTX:全功能 MQTT 客户端工具

4.broker部署

如果你要部署broker就看一下官方文档,https://hub.docker.com/_/eclipse-mosquitto(这个需要翻墙),不会翻的话抽空学一下,很有用;不会翻百度一下mosquitto部署,有很多。。

记录一下,用于学习交流,业务相关代码不展示了,如果哪里有问题欢迎交流、指正。

  • 17
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: MQTT(Message Queuing Telemetry Transport)协议是一种轻量级的发布/订阅消息传输协议,常用于物联网设备之间的通信。下面是使用MQTT协议的一般步骤: 1. 安装MQTT broker:MQTT broker是负责接收和转发消息的服务器。可以在本地计算机上安装,也可以使用云服务商提供的MQTT broker。常见的MQTT broker有Mosquitto、EMQ X、HiveMQ等。 2. 创建MQTT客户端:使用MQTT协议进行通信的设备需要安装MQTT客户端。一些编程语言,如Python、Java、C++等,提供了MQTT客户端的库。您可以使用这些库创建MQTT客户端并与MQTT broker通信。 3. 连接MQTT broker:MQTT客户端需要连接MQTT broker才能发送和接收消息。连接MQTT broker需要指定MQTT broker的IP地址和端口号。 4. 发布消息:MQTT客户端可以发布消息到MQTT broker,以便其他订阅该主题的客户端可以接收该消息。要发布消息,需要指定消息的主题和内容。 5. 订阅消息:MQTT客户端可以订阅特定的主题,以接收发布到该主题的所有消息。当发布到该主题的新消息可用时,MQTT broker会将其推送到所有订阅该主题的客户端。 下面是一个Python程序示例,该程序使用paho-mqtt库创建MQTT客户端,并发布和订阅主题。 ```python import paho.mqtt.client as mqtt # 定义回调函数 def on_connect(client, userdata, flags, rc): print("Connected with result code " + str(rc)) client.subscribe("test/topic") def on_message(client, userdata, msg): print(msg.topic + " " + str(msg.payload)) # 创建MQTT客户端 client = mqtt.Client() # 设置回调函数 client.on_connect = on_connect client.on_message = on_message # 连接MQTT broker client.connect("localhost", 1883, 60) # 发布消息 client.publish("test/topic", "Hello, World!") # 订阅消息 client.loop_forever() ``` 在这个例子中,客户端连接到本地计算机上运行的MQTT broker,并发布消息到名为“test/topic”的主题。此外,客户端还订阅该主题,以接收发布到该主题的所有消息。当客户端收到新的消息时,它会调用on_message回调函数来处理消息。 请注意,上面的示例仅用于演示MQTT协议的基本用法。在实际应用程序中,您需要考虑安全性、数据格式、消息质量等问题。 ### 回答2: MQTT(Message Queuing Telemetry Transport)是一种轻量级的消息传输协议,常用于物联网设备之间的通信。 使用MQTT协议的流程如下: 1. 客户端连接到MQTT代理服务器。客户端需要知道代理服务器的IP地址、端口号和连接参数,包括客户端ID、用户名和密码等。 2. 客户端发送CONNECT消息给代理服务器,用于建立连接。连接建立后,客户端可以发送和接收消息。 3. 客户端可以选择订阅一个或多个主题(Topic)。主题是消息的分类,可以是任意字符串,用于识别消息的类型或内容。 4. 客户端可以发送PUBLISH消息给代理服务器,发布消息到指定的主题。消息可以是任意格式的数据,例如传感器数据、控制命令等。 5. 当有其他客户端发布消息到订阅的主题时,客户端会收到PUBLISH消息。客户端可以根据自己的需求处理接收到的消息。 6. 客户端可以选择取消订阅某个主题,不再接收该主题下的消息。客户端也可以断开与代理服务器的连接。 使用MQTT协议时需要注意以下事项: 1. 客户端和代理服务器之间的连接需要保持活动状态,即保持心跳,以确保连接不会断开。 2. 使用QoS(Quality of Service)等级来确保消息的可靠性。QoS级别包括0、1和2,级别越高,消息的可靠性越高,但传输效率也会降低。 3. 需要合理设置主题和订阅规则,以便客户端能够接收到感兴趣的消息。 4. 可以使用MQTT客户端库来简化开发流程,例如paho-mqtt库。 总之,使用MQTT协议可以方便地实现设备之间的消息传输和通信,为物联网应用提供了一种可靠、高效的解决方案。 ### 回答3: MQTT(Message Queuing Telemetry Transport)是一种基于发布/订阅模式的轻量级通信协议,广泛应用于物联网设备和应用程序之间的通信。 使用MQTT协议需要以下几个步骤: 1. 建立连接:首先需要建立与MQTT服务器(或代理)的连接。通常使用TCP/IP协议作为底层传输协议,通过指定端口号(默认为1883)连接到服务器。也可以通过SSL/TLS加密连接以提高安全性(默认端口为8883)。 2. 设置发布/订阅主题:MQTT使用发布/订阅模式进行消息传递,消息以主题进行分类。在连接到服务器后,订户(客户端)需要指定订阅的主题,而出版者(客户端)需要指定发布的主题。 3. 发布消息:出版者可以向指定的主题发布消息。发布消息时,需要指定主题和消息内容。 4. 订阅消息:订户可以订阅感兴趣的主题,以接收相应的消息。订户需要指定主题,并设置消息传递的质量等级。 5. 接收和处理消息:订户可以通过消息回调函数接收到订阅的消息。在消息到达时,回调函数会被触发,订户可以根据具体需求对接收到的消息进行处理。 6. 断开连接:在不需要使用MQTT协议时,应及时断开连接。可以发送断开连接请求到服务器来关闭连接。如果长时间不发送心跳包,服务器也会主动断开连接。 总结起来,使用MQTT协议需要先建立与服务器的连接,设置发布/订阅主题,然后通过发布消息和订阅消息进行通信。使用回调函数接收和处理消息,最后断开连接。这样就可以在物联网设备和应用程序之间实现轻量级、可靠的通信。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值