mqtt介绍与安装 spring boot集成mqtt 优缺点 linux centOS 7设置开机自启

该教程将从mqtt的介绍——>优缺点——>linux centOS 7系统下安装部署mqtt——>并加入开机自启——>spring boot集成mqtt——>最后进行验证的全部流程。

目录

二、专业术语

三、MQTT的优缺点

四、MQTT安装

五、spring boot集成MQTT

六、验证


        MQTT协议全称Meaage Queuing Telemetry Transport 消息队列遥测传输协议。

        它是一种基于订阅/发布(Publish/Subscribe)模式的轻量级通讯协议,用于物联网(IoT)设备之间的通讯。该协议构建于TCP/IP协议之上,因TCP协议本身具有高可靠性特点,因此MQTT同样具有高可靠、低开销的特点,之所以低开销,是因为MQTT协议传输的最小报文只有两个字节。

        MQTT协议有三种身份,发布者(Publish)、代理(Broker服务器)、订阅者(Subscribe)。发布者和订阅者都为客户端,消息代理为服务器,发布者也可以是订阅者。

二、专业术语

1.网络连接Network Connection

        MQTT使用底层传输协议TCP基础设施,客户端使用它连接服务器,它提供有序的、可靠的、双向字节流传输。

2.应用消息Application Message

        MQTT协议通过网络传输应用数据,应用消息通过MQTT传输时,需要有关联的服务质量(QoS)和主题(Topic)。

3.客户端Client

        使用MQTT的程序或设备,客户端总是通过网络连接到服务器,它可以:

        1)发布应用消息给其他相关的客户端。

        2)订阅接收相关的应用消息。

        3)取消订阅—移除接收应用消息的请求。

        4)从服务端断开连接。

4.服务器Server

        一个程序或设备,作为发送消息的客户端和请求订阅的客户端之间的中介。

        1)接收来自客户端的网络连接。

        2)接收客户端发布的应用消息。

        3)处理客户端的订阅和取消订阅请求。

        4)转发应用消息给符合条件的已订阅客户端。

5.订阅Subscribe

        订阅包含一个主题过滤器(Topic Filter)和一个最大的服务质量(QoS)等级。订阅与单个会话(session)关联。会话可以包含多于一个的订阅。会话的每个订阅都有一个不同的主题过滤器。

6.主题名Topic Name

        附加再应用消息上的一个标签,服务端已知且与订阅匹配。服务端发送应用消息的每一个副本给每一个匹配的客户端订阅。

7.主题过滤器Topic Filter

        订阅中包含的一个表达式,用于表示相关的一个或多个主题。主题过滤器可以使用通配符。

8.会话session

        客户端和服务端之间的状态交互。一些会话持续时长与网络连接一样,另一些可以在客户端和服务端的多个连续网络连接间扩展。

9.控制报文MQTT Control Packet

通过网络连接发送的信息数据包。MQTT规范定义了十四种不同类型的控制报文,其中一个(Publish报文)用于传输应用消息。

10.消息质量(QoS)
        MQTT消息质量有三个等级,QoS 0、QoS 1和QoS 2。

        QoS 0:最多分发一次。消息的传递完全依赖底层的TCP/IP网络,协议里没有定义答应和重试,消息要么只会到达服务端一次,要么根本没有到达。消息可能会丢失。

        QoS 1:最少分发一次。服务器的消息接收由puback消息进行确认,如果通信链路或发送设备异常,或者指定时间内没有收到确认消息,发送端会重发这条再消息头中设置了DUP位的消息。

        QoS 2:只分发一次。这是最高级别的消息传递,消息丢失和重复都是不可接受的,使用这个服务质量等级,会有额外的开销。例如,这个等级可用在一个计费系统中,这里如果消息重复或丢失会导致不正确的收费。

三、MQTT的优缺点

1.优点

        轻量级:MQTT协议非常简单,头部只有2字节,开销小,适合网络带宽和内存资源有限的设备。

        发布/订阅模式:MQTT采用发布/订阅模式,解除了发送方和接收方的耦合,适合处理大量的消息路由。

        稳定性:MQTT支持断开重连,确保了网络的稳定性。

        低延迟:MQTT采用心跳机制,可以保证消息的实时传输。

        扩展性:MQTT支持Last Will和Testament特性,可以在客户端异常断开时通知其他客户端。

2.缺点

        不支持复杂的数据类型:MQTT只支持字符串和二进制数据,不支持更复杂的数据类型。

        不支持服务质量保证:虽然MQTT支持QoS,但是并没有在协议层面保证消息的顺序和不重复,需要应用层实现。

        不支持服务发现:客户端需要知道服务端的地址,服务端的动态发现需要其他机制支持。

四、MQTT安装

版本信息:

        系统:linux-centOS 7

        mqtt版本:mosquitto-2.0.14.tar.gz

        cJSON库:点击下载

1.上传mosquitto与cJSON到服务器/opt目录,并解压

[root@bogon /]# cd opt/
[root@bogon opt]# ll
drwxr-xr-x.  5 root  root      4096 5月  16 16:13 cJSON
drwxrwxr-x. 20  1000 mysql     4096 5月  16 16:08 mosquitto-2.0.14

2.安装相关依赖与cJSON库

[root@bogon opt]# yum install -y c-ares-devel e2fsprogs-devel uuid-devel libuuid-devel
[root@bogon opt]# yum install libssl-dev libc-ares-dev uuid-dev daemon openssl-devel
[root@bogon opt]# cd cJSON
[root@bogon cJSON]# make && make install

3.安装mosquitto

[root@bogon cJSON]# cd ../mosquitto-2.0.14
[root@bogon mosquitto-2.0.14]# make && make install

4.修改mosquitto.conf配置文件

[root@bogon mosquitto-2.0.14]# vi mosquitto.conf
#加入以下配置
listener 1883 0.0.0.0    #允许所有电脑访问
allow_anonymous true     #匿名登录,客户端连接不需要密码

5.加入开机自启

[root@bogon mosquitto-2.0.14]# vi /lib/systemd/system/mosquitto.service
#-------加入以下配置,然后保存----------
[Unit]
Description=Mosquitto MQTT Broker
After=network.target

[Service]
ExecStart=/usr/local/sbin/mosquitto -c /opt/mosquitto-2.0.14/mosquitto.conf
[Install]
WantedBy=multi-user.target
#---------------end--------------------

[root@bogon mosquitto-2.0.14]# systemctl daemon-reload        #重新加载
[root@bogon mosquitto-2.0.14]# systemctl start mosquitto      #启动mqtt服务
[root@bogon mosquitto-2.0.14]# systemctl enable mosquitto     #加入开机自启

五、spring boot集成MQTT

1.新建spring boot项目,然后再pom.xml添加相关依赖包

<!-- spring boot 依赖包 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.18.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- mqtt依赖包 -->
    <dependency>
        <groupId>org.springframework.integration</groupId>
        <artifactId>spring-integration-mqtt</artifactId>
    </dependency>
</dependencies>

2.application.yml增加配置

#MQTT配置
mqtt:
  host: tcp://localhost:1883
  userName: root
  passWord: 123456
  clientid: client1
  timeout: 10
  keepalive: 60

3.新建MyMqttCallback消息回调类

package com.example.demo.common.mqtt;

import com.example.demo.common.config.MqttConfiguration;
import org.eclipse.paho.client.mqttv3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * MQTT消息订阅回调类
 */
@Component
public class MyMqttCallback implements MqttCallback {
    @Autowired
    private MqttConfiguration mqttConfiguration;

    /**
     * MQTT连接中断,重连
     */
    @Override
    public void connectionLost(Throwable throwable) {
        System.out.println("[connectionLost]方法,MQTT断开连接,发起重新连接");
        mqttConfiguration.getMyMqttClient();
    }

    /**
     * 接收订阅消息
     * @param s
     * @param MqttMessage
     * @throws Exception
     */
    @Override
    public void messageArrived(String s, MqttMessage mqttMessage) {
        System.out.println("收到消息主题:" + s + ", 消息内容:" + new String(MqttMessage.getPayload()));
    }

    /**
     * 发送订阅消息成功后
     * @param iMQTTDeliveryToken
     */
    @Override
    public void deliveryComplete(IMQTTDeliveryToken iMQTTDeliveryToken) {
        System.out.println("deliveryComplete消息发送成功,处理业务逻辑");
    }
}

4.新建MyMqttClient客户端类

package com.example.demo.common.mqtt;

import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * MQTT客户端
 */
@Component
public class MyMqttClient {
    @Autowired
    private MyMqttCallback myMqttCallback;
    private MqttClient mqttClient;

    /**
     * 连接MQTT
     * @param host
     * @param ClientId
     * @throws MQTTException
     */
    public void connect(String username, String password, String host, String clientId, int timeout, int keepalive) {
        //设置参数
        MqttConnectOptions options = new MqttConnectOptions();
        options.setUserName(username);
        options.setPassword(password.toCharArray());
        options.setConnectionTimeout(timeout);
        options.setKeepAliveInterval(keepalive);
        options.setCleanSession(true);
        options.setAutomaticReconnect(true);
        //启动项目连接失败,每2秒进行一次重连
        while (true) {
            try {
                if (null == mqttClient) {
                    mqttClient = new MqttClient(host, clientId, new MemoryPersistence());
                    mqttClient.setCallback(myMqttCallback);
                }
                if (mqttClient.isConnected()) {
                    //连接成功,中断重连机制
                    break;
                }
                mqttClient.connect(options);
                Thread.sleep(2000);
            } catch (Exception e) {
                System.out.println("[connect]方法,启动服务连接MQTT失败!");
                e.printStackTrace();
            }

        }
        System.out.println("[connect]方法,启动服务连接MQTT成功!");
    }

    /**
     * 发布消息
     */
    public void publish(String topic, String message) {
        this.publish(topic, message, 0, false);
    }

    /**
     * 发送消息
     * @param Topic
     * @param mesage
     * @param QoS
     * @param retained
     */
    public void publish(String topic, String message, int qos, boolean retained) {
        MqttMessage mqttMessage = new MqttMessage();
        MqttMessage.setPayload(mesage.getBytes());
        MqttMessage.setQos(qos);
        MqttMessage.setRetained(retained);
        try {
            this.mqttClient.getTopic(topic).publish(mqttMessage);
        } catch (MqttException e) {
            System.out.println("[publish]方法,发送消息异常!");
            e.printStackTrace();
        }
    }

    /**
     * 订阅
     */
    public void subscribe(String topic, int qos) {
        try {
            mqttClient.subscribe(topic, qos);
        } catch (MqttException e) {
            System.out.println("[Subscribed]方法,订阅主题异常!");
            e.printStackTrace();
        }
    }

    /**
     * 取消订阅
     * @param Topic
     */
    public void cleanTopic(String topic) {
        try {
            mqttClient.unsubscribe(topic);
        } catch (MqttException e) {
            System.out.println("[cleanTopic]方法,取消订阅主题异常!");
            e.printStackTrace();
        }
    }
}

5.新建MqttConfiguration配置类

package com.example.demo.common.config;

import com.example.demo.common.mqtt.MyMqttClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

/**
 * MQTT消息配置类
 */
@Component
public class MqttConfiguration {
    @Autowired
    private MyMqttClient myMqttClient;
    @Value("${mqtt.host}")
    String host;
    @Value("${mqtt.username}")
    String username;
    @Value("${mqtt.password}")
    String password;
    @Value("${mqtt.clientId}")
    String clientId;
    @Value("${mqtt.timeout}")
    int timeout;
    @Value("${mqtt.keepalive}")
    int keepalive;

    @Bean
    public MyMqttClient getMyMqttClient() {
        try {
            //连接服务器
            myMqttClient.connect(username, password, host, clientId, timeout, keepalive);
            //订阅相关主题
            myMqttClient.subscribe("A/pick/warn/#", 1);
            myMqttClient.subscribe("A/cmd/resp", 1);
            myMqttClient.subscribe("ABCH", 1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return myMqttClient;
    }
}

六、验证

1.编写测试类DemoController,并启动服务

package com.example.demo.controller;

import com.example.demo.common.config.mqtt.MyMqttClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {
    @Autowired
    private MyMqttClient myMqttClient;
    @RequestMapping("/demo")
    public boolean demo(@RequestParam("topic") String topic, @RequestParam("message") String mesage) {
        myMqttClient.publish(topic, mesage);
        return true;
    }
}

2.浏览器访问测试接口,给A/cmd/resp队列发送aaaa消息

3.后端服务打印收到的消息

  • 27
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天道酬勤-L

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值