MQTT详解以及在IoT中的应用
MQTT定义:
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和制动器的通信协议。
MQTT简介:
MQTT是基于客户端/服务器的二进制的发布、订阅编程模式的消息协议,由于规范简单,非常适用于带宽低,低功耗的iot场景,比如:遥感、M2M、智慧城市、智能家居、医疗医护等。由于物联网的环境非常的特别,所以MQTT有他的设计规范:
- 精简,不添加可有可无的功能
- 发布、订阅模式,方便消息在传感器之间传递
- 允许用户动态创建主题,零运维成本
- 把传输量降到最低提高传输效率
- 考虑地带宽、高延迟、不稳定的网络因素
- 充分理解客户端羸弱的计算能力
- 支持连续会话
- 提供服务质量管理。(Qos:至少一次、至多一次、只有一次)
- 假设数据不可知,不强求数据的类型和格式,保持灵活性
mqtt发布订阅模式:
和传统的http的请求/应答模式不一样(request/response),发布订阅模式解耦了发布者和订阅者之间的关系,这意味着发布者和订阅者不需要直接联系,由代理进行转发,什么意思呢?打个比方你打电话给你的女朋友翟小树,需要等翟小树接听电话之后你们才可以交流,这个就是http的请求响应模式,试想你是一个大明星,胡大橙和翟小树都关注了你的微博,当你发布一条微博的时候,微博服务器就是转发给他们两个的好友动态,此时你就是发布者(publisher),他们就是订阅者(subscribe),就这事典型的异步发布订阅模式。发布订阅模式带来了一些好处:
- 发布者和订阅者不必彼此了解,多个订阅者之间也不需要彼此了解,只需要认识同一个消息代理
- 发布者和订阅者不需要同时在线
- 发布者和订阅者不需要进行任何的交互
为了满足不同的场景,mqtt支持三种不同的服务质量(Qos)
- 最多一次 (基于tcp/ip,发布者会想尽办法发布,但是遇到意外不会重试,使用场景比如传感器上报数据某次丢失但是过几秒就会另一次上报,对数据的要求不是那么的精确就可以设置这种)
- 至少一次 (如果订阅者没有收到,发布者会重复的发送,确保消息达到,但是这种会存在一种问题就是重复的接收消息)
- 只有一次(缺点是减少了并发或者增加了延时,但是如果消息重复或者丢失都不可接收的时候,这种最合适)。
MQTT协议原理:
实现mqtt协议需要客户端和服务端,这个流程有三个角色,发布者(publish)、订阅者(subscribe)、代理,其中发布者可以是某个topic的发布者,也可以是另一个topic的订阅者。
mqtt的消息分为两个部分:主题(topic)、负载(payload)。
- topic:消息的类型,订阅者订阅了该消息之后就会收到代理转发的消息。
- payload:消息的内容。
MQTT客户端:
- 发布订阅者可能订阅的消息
- 订阅其他客户端可能发布的消息
- 退订或删除应用程序的消息
- 断开与服务器的连接
MQTT服务端:
- 接收来自客户端的连接
- 接收客户端发布的消息
- 转发订阅对应topic的消息给订阅者
- 处理来自客户端的订阅和退订请求
MQTT协议中的一些方法:
- connect:与服务端进行连接

- disconnect 等客户端完成所有工作后断开与服务器的tcp/ip连接

- publish 客户端发布消息

- subscribe 客户端订阅主题(异步过程)

- unsubscribe 等待服务器取消客户端的一个或多个订阅的topic(异步过程)

MQTT在IoT中的实践

这是一张典型的MQTT在IoT中的应用,其中app作为客户端,智能网关也作为客户端(实际上在我们公司的V6云平台也是作为客户端),物联网云服务作为统一的服务端负责收发,app和V6云订阅同一个主题,app和网关订阅另一个主题,当每次需要发送mqtt命令时首先判断是账号登录(V6云)还是网关登录,于此publish对应的topic和payload,物联网云服务收到mqtt消息后转发给订阅同一个topic主题的客户端(V6云或者网关),然后通过再由网关发送对应的指令去控制低功耗设备(比如门锁的开关,灯泡的开关)。这个时候可以看出topic的重要性,合理的定义topic可以实现不同业务功能。先说一下我们公司的topic的定义,由于初期没有考虑周到,只是针对V6云和网关定义了两个不同的topic,导致后面有一项业务功能是给分享的账号发一些mqtt消息时导致V6云需要做大量的过滤,完全没有体现出topic的优势,接下来先讲一下topic主题设计。
Topic主题设计
主题层级分隔符:“/” 主题层级分隔符是的主题十分结构化
china/jiangsu/nanjing- shanghuang/xiadayu
- shanghuang/huxiangli/81hao
多层通配符:"#’ 是用于匹配主题中任意层级的通配符。多层通配符表示它的父级和任意数量的子层级。多层通配符必须位于它自己的层级或者跟在主题层级分隔符后面。不管哪种情况,它都必须是主题过滤器的最后一个字符 .比如你订阅了一个jiangsu/nanjing/*,你会收到如下的主题的消息
- jiangsu/nanjing
- jiangsu/nanjing/jiangning
- jiangsu/nanjing/qixia/nanjingdaxue
定阅主题示例
- jiangsu/# //也单独匹配“江苏”,因为#包括他的父级。
- # //有效,会收到所有的topic的消息
- jiangsu/nanjing/* //有效
- jiangsu/nanjing* //无效
- jiangsu/#/nanjing //无效,必须是主题过滤器的最后一个字符
单层通配符 “+” 只能用于单个层级匹配的通配符,在主题过滤器的任意层级都可以使用单层通配符,包括第一个和最后一个层级。然而它必须占据过滤器的整个层级 。可以在主题过滤器中的多个层级中使用它,也可以和多层通配符起使用。举个栗子:
- china/+ 只能匹配china/jiangsu
- china/+/+/zhaixiaoshu 可以匹配 china/xianlin/nanda/zhaixiaoshu 或者china/shanghuang/xiadayu/zhaixiaoshu
总结一下
- 所有的主题名和主题过滤器必须至少包含一个字符
- 主题名或主题过滤器以前置或后置斜杠 “/” 区分
- 只包含斜杠 “/” 的主题名或主题过滤器是合法的
- 主题名和主题过滤器是 UTF-8 编码字符串, 它们不能超过 65535 字节
- 主题名和主题过滤器是区分大小写的
从上可以看出合理的topic订阅能够实现花样的功能,就比如当初设计分享的用户的时候完全可以用通配符去设计,可以大大的减小计算和筛选量。

MQTT详解以及在IoT中的应用的更多相关文章
- Scala 深入浅出实战经典 第61讲:Scala中隐式参数与隐式转换的联合使用实战详解及其在Spark中的应用源码解析
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...
- Scala 深入浅出实战经典 第60讲:Scala中隐式参数实战详解以及在Spark中的应用源码解析
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- 详解OJ(Online Judge)中PHP代码的提交方法及要点【举例:ZOJ 1001 (A + B Problem)】
详解OJ(Online Judge)中PHP代码的提交方法及要点 Introduction of How to submit PHP code to Online Judge Systems Int ...
- 详解Linux下iptables中的DNAT与SNAT设置(转)
详解Linux下iptables中的DNAT与SNAT设置 这篇文章主要介绍了Linux下iptables中的DNAT与SNAT设置,是Linux网络配置中的基础知识,需要的朋友可以参考下 原文连 ...
- Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制
Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制 JAVA 中原生的 socket 通信机制 摘要:本文属于原创,欢迎转载,转载请保留出处:https://github.co ...
- 详解在Linux系统中安装Tomcat
本文以在CentOS 7.6中安装Tomcat8.5为例进行安装,其他系统和版本都是大同小异的. 安装JDK 安装Tomcat之前,需要先安装JDK,可以参看之前的文章详解在Linux系统中安装JDK ...
- 详解如何在CentOS7中使用Nginx和PHP7-FPM安装Nextcloud
转载地址:https://www.jb51.net/article/109382.htm 这篇文章主要介绍了详解如何在CentOS7中使用Nginx和PHP7-FPM安装Nextcloud,会通过 N ...
- 详解如何在Laravel中增加自定义全局函数
http://www.php.cn/php-weizijiaocheng-383928.html 如何在Laravel中增加自定义全局函数?在我们的应用里经常会有一些全局都可能会用的函数,我们应该怎么 ...
- 第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法
第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法 上节介绍了Python中类的静态方法,本节将结合案例详细说明相关内容. 一. 案例说明 本节定义了类Sta ...
随机推荐
- 第三篇: 服务消费者(Feign)
本文根据https://blog.csdn.net/forezp/article/details/81040965写出,修正了部分瑕疵,在此对那位博主表示感谢. 上一篇文章讲述通过RestTempla ...
- Git查看远程提交状态的方法
git使用过程中,经常遇到这样的问题,已经git push 了,但是,由于冲突或者push的分支不对,导致远程的和本地的不一致. 这就需要提交后查看一下远程的是否ok. 查了一下资料,找到了一些方法, ...
- .NET手记-JS获取Url参数
最近为App做活动专区,其中很多活动都是采用html 5页面来制作的.一方面体量较小,制作快速,更新维护容易:另一方面,嵌入App后适配效果也不会很差. 这里我们采用混编形式来从native app传 ...
- 阿里P9架构师讲解从单机至亿级流量大型网站系统架构的演进过程
阶段一.单机构建网站 网站的初期,我们经常会在单机上跑我们所有的程序和软件.此时我们使用一个容器,如tomcat.jetty.jboos,然后直接使用JSP/servlet技术,或者使用一些开源的框架 ...
- Centos 7 安装 rabbitmq
1.安装erlang rabbitmq 官方下载地址 "http://www.rabbitmq.com/download.html" ,选择"RHEL, CentOS, ...
- BF算法(模式匹配)
BF算法 (Brute-Force算法) 一种简单的模式匹配算法,目的是寻找模式串p是否在目标串s中有出现. 思想:先从第一个字符开始匹配,如果p[j]==s[i],那么继续向下比较,一旦不相等,即回 ...
- jdk8- list操作
本文版权归 远方的风lyh和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. student类 public class Student { private String age; ...
- 细说spring事务配置属性
一.spring事务配置 1.spring配置 在配置数据源的下方配置 <!-- 事务配置 --> <bean id="transactionManager" c ...
- Ribbon使用Hystrix
1.导入依赖spring-cloud-starter-hystrix <dependency> <groupId>org.springframework.cloud</g ...
- Eclipse Gradle 构建多模块项目
注意: 1.Eclipse不如IDEA智能,Eclipse建立的Gradle Project项目在目录级别上是同级的; 2.user-web模块如果要引用user-service模块,直接引用是找不到 ...