Java实践-物联网loT入门-MQTT传输协议

news/2024/10/17 10:24:36/

前言

MQTT是一个极其轻量级发布/订阅消息传输协议,适用于网络带宽较低的场合.

通过一个代理服务器(broker),任何一个客户端(client)都可以订阅或者发布某个主题的消息,然后订阅了该主题的客户端则会收到该消息

业务场景

硬件采集的数据传入EMQX平台(采用MQTT协议),java通过代码连接MQTT服务器,进行采集数据接收、解析、业务处理、存储入库、数据展示。

MQTT 是基于 发布(Publish)/订阅(Subscribe) 模式来进行通信及数据交换的。

什么是MQTT

MQTT是基于二进制消息的发布/订阅编程模式的消息协议,最早由IBM提出的,如今已经成为OASIS规范。由于规范很简单,非常适合需要低功耗和网络带宽有限的IoT场景,比如:

  • 遥感数据
  • 汽车
  • 智能家居
  • 智慧城市
  • 医疗医护

由于物联网的环境是非常特别的,所以MQTT遵循以下设计原则:

  1. 精简,不添加可有可无的功能。
  2. 发布/订阅(Pub/Sub)模式,方便消息在传感器之间传递。
  3. 允许用户动态创建主题,零运维成本。
  4. 把传输量降到最低以提高传输效率。
  5. 把低带宽、高延迟、不稳定的网络等因素考虑在内。
  6. 支持连续的会话控制。
  7. 理解客户端计算能力可能很低。
  8. 提供服务质量管理。
  9. 假设数据不可知,不强求传输数据的类型与格式,保持灵活性。

MQTT与HTTP的区别

首先看一下HTTP请求:

  • HTTP 是一种同步协议。客户端需要等待服务器响应。Web 浏览器具有这样的要求,但它的代价是牺牲了可伸缩性。
  • HTTP 是单向的。客户端必须发起连接。
  • HTTP 是一种 1-1 协议。客户端发出请求,服务器进行响应。将消息传送到网络上的所有设备上,不但很困难,而且成本很高。
  • HTTP 是一种有许多标头和规则的重量级协议。它不适合受限的网络。

再来看一下MQTT: 

        在 IoT 领域,大量设备以及很可能不可靠或高延迟的网络使得同步通信成为问题。异步消息协议更适合 IoT 应用程序。传感器发送读数,让网络确定将其传送到目标设备和服务的最佳路线和时间。在 IoT 应用程序中,设备或传感器通常是客户端,这意味着它们无法被动地接收来自网络的命令。

MQTT的核心: 发布和订阅模型 

MQTT 协议在网络中定义了两种实体类型:一个消息代理和一些客户端。

代理是一个服务器,它从客户端接收所有消息,然后将这些消息路由到相关的目标客户端。

客户端是能够与代理交互来发送和接收消息的任何事物。客户端可以是现场的 IoT 传感器,或者是数据中心内处理 IoT 数据的应用程序。

  1. 客户端连接到代理。它可以订阅代理中的任何消息“主题”。此连接可以是简单的 TCP/IP 连接,也可以是用于发送敏感消息的加密 TLS 连接。
  2. 客户端通过将消息和主题发送给代理,发布某个主题范围内的消息。
  3. 代理然后将消息转发给所有订阅该主题的客户端。

        同时,MQTT 是轻量级的。它有一个用来指定消息类型的简单标头,有一个基于文本的主题,还有一个任意的二进制有效负载。应用程序可对有效负载采用任何数据格式,比如 JSON、XML、加密二进制或 Base64,只要目标客户端能够解析该有效负载。

Java实例

1.通过包管理工具 Maven导入依赖

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

 2.编写订阅方的代码,并启动。

import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;/*** 订阅方*/
public class SubscribeSample {public static void main(String[] args) {//EMQ X 默认端口 1883String broker = "tcp://broker.emqx.io:1883";String TOPIC = "test";int qos = 1;String clientid = "subClient";String userName = "admin";String passWord = "password";try {// host为主机名,test为clientid即连接MQTT的客户端ID,一般以客户端唯一标识符表示,MemoryPersistence设置clientid的保存形式,默认为以内存保存MqttClient client = new MqttClient(broker, clientid, new MemoryPersistence());// MQTT的连接设置MqttConnectOptions options = new MqttConnectOptions();// 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接options.setCleanSession(true);// 设置连接的用户名options.setUserName(userName);// 设置连接的密码options.setPassword(passWord.toCharArray());// 设置超时时间 单位为秒options.setConnectionTimeout(10);// 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制options.setKeepAliveInterval(20);// 设置回调函数client.setCallback(new MqttCallback() {public void connectionLost(Throwable cause) {System.out.println("connectionLost");}public void messageArrived(String topic, MqttMessage message) {System.out.println("======监听到来自[" + topic + "]的消息======");System.out.println("message content:"+new String(message.getPayload()));System.out.println("============");}public void deliveryComplete(IMqttDeliveryToken token) {System.out.println("deliveryComplete---------"+ token.isComplete());}});// 建立连接System.out.println("连接到 broker: " + broker);client.connect(options);System.out.println("连接成功.");//订阅消息client.subscribe(TOPIC, qos);System.out.println("开始监听" + TOPIC);} catch (Exception e) {e.printStackTrace();}}
}

启动订阅方运行结果如下:

 

3.编写发布方的代码并启动

import org.eclipse.paho.client.mqttv3.MqttClient;
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.persist.MemoryPersistence;/*** 发布方*/
public class PublishSample {public static void main(String[] args) {String topic = "test";String content = "你好,我给你发了条消息呀!!!!!!!!!!!";int qos = 1;String broker = "tcp://broker.emqx.io:1883";String userName = "admin";String password = "password";String clientId = "pubClient";// 内存存储MemoryPersistence persistence = new MemoryPersistence();try {// 创建客户端MqttClient sampleClient = new MqttClient(broker, clientId, persistence);// 创建链接参数MqttConnectOptions connOpts = new MqttConnectOptions();// 在重新启动和重新连接时记住状态connOpts.setCleanSession(false);// 设置连接的用户名connOpts.setUserName(userName);connOpts.setPassword(password.toCharArray());// 建立连接System.out.println("连接到 broker: " + broker);sampleClient.connect(connOpts);System.out.println("连接成功.");// 创建消息MqttMessage message = new MqttMessage(content.getBytes());// 设置消息的服务质量message.setQos(qos);// 发布消息System.out.println("向" + topic + "发送消息:" + message);sampleClient.publish(topic, message);// 断开连接sampleClient.disconnect();// 关闭客户端sampleClient.close();} catch (MqttException me) {System.out.println("reason " + me.getReasonCode());System.out.println("msg " + me.getMessage());System.out.println("loc " + me.getLocalizedMessage());System.out.println("cause " + me.getCause());System.out.println("excep " + me);me.printStackTrace();}}
}

 

启动发布方运行结果如下:

4.最后查看订阅方的控制台,订阅方收到消息

 


http://www.ppmy.cn/news/1095907.html

相关文章

[C题]2023 年全国大学生数学建模比赛思路、代码更新中.....

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【前端基础】js 如何判断一个值是数组

在JavaScript中&#xff0c;可使用不同的方法来判断一个值是否是一个数组。以下是一些常用的方法&#xff1a; 使用 Array.isArray() 方法&#xff1a; if (Array.isArray(value)) {// 值是一个数组 } else {// 值不是一个数组 }Array.isArray() 方法是最简单和推荐的方法&…

利用观测云实现业务数据驱动的弹性扩缩容

背景 在使用观测云对业务系统进行观测的过程中&#xff0c;除了可以实现业务系统的全面感知&#xff0c;我们还可以基于观测云数据处理开发平台 DataFlux Func &#xff0c;结合故障模型对被测系统进行主动管理&#xff0c;例如弹性扩容或系统故障自愈&#xff0c;从而实现系统…

vim常用操作

一、Esc键 & 命令模式 1.撤销&#xff1a;u 恢复撤销&#xff1a;Ctrl r 2.定位 行首&#xff1a;0 行尾&#xff1a;$ 第7行&#xff1a;7G 3.编辑 下行开始插入&#xff1a; o 删除行&#xff1a;dd 复制3行并粘贴&#xff1a;3yy ---> p 复制单词并粘贴&#…

DC电源模块的使用寿命问题

BOSHIDA DC电源模块的使用寿命问题 DC电源模块是一种电子元器件&#xff0c;它为电路提供稳定的直流电压和电流。在电子产品中&#xff0c;DC电源模块往往是核心部件之一&#xff0c;其使用寿命与产品的整体性能密切相关。 使用寿命是DC电源模块的重要参数之一。使用寿命是指…

(其他) 剑指 Offer 46. 把数字翻译成字符串 ——【Leetcode每日一题】

❓ 剑指 Offer 46. 把数字翻译成字符串 难度&#xff1a;中等 给定一个数字&#xff0c;我们按照如下规则把它翻译为字符串&#xff1a;0 翻译成 “a” &#xff0c;1 翻译成 “b”&#xff0c;……&#xff0c;11 翻译成 “l”&#xff0c;……&#xff0c;25 翻译成 “z”。…

2023年7月京东奶粉行业品牌销售排行榜(京东数据产品)

鲸参谋监测的京东平台7月份奶粉市场销售数据已出炉&#xff01; 根据鲸参谋平台的数据显示&#xff0c;今年7月份&#xff0c;京东奶粉市场的销量为600万&#xff0c;同比去年同期有所下滑&#xff0c;整体下降约21%&#xff1b;销售额为22亿&#xff0c;同比增长约9%。由此也…

索尼 toio™应用创意开发征文|toio俄罗斯方块游戏

目录 引言 摘要 创意简述 准备工作&#xff5c;手工开始 代码编写&#xff5c;合理集成 使用体验&#xff5c;近乎奇妙 引言 索尼toio™编程机器人是一款引领技术创新的产品&#xff0c;为开发者提供了一个全新的编程和创造平台。toio™的设计旨在将技术、塑性和乐趣融为…