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中的应用的更多相关文章

  1. Scala 深入浅出实战经典 第61讲:Scala中隐式参数与隐式转换的联合使用实战详解及其在Spark中的应用源码解析

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...

  2. Scala 深入浅出实战经典 第60讲:Scala中隐式参数实战详解以及在Spark中的应用源码解析

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  3. 详解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 ...

  4. 详解Linux下iptables中的DNAT与SNAT设置(转)

    详解Linux下iptables中的DNAT与SNAT设置 这篇文章主要介绍了Linux下iptables中的DNAT与SNAT设置,是Linux网络配置中的基础知识,需要的朋友可以参考下   原文连 ...

  5. Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制

    Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制 JAVA 中原生的 socket 通信机制 摘要:本文属于原创,欢迎转载,转载请保留出处:https://github.co ...

  6. 详解在Linux系统中安装Tomcat

    本文以在CentOS 7.6中安装Tomcat8.5为例进行安装,其他系统和版本都是大同小异的. 安装JDK 安装Tomcat之前,需要先安装JDK,可以参看之前的文章详解在Linux系统中安装JDK ...

  7. 详解如何在CentOS7中使用Nginx和PHP7-FPM安装Nextcloud

    转载地址:https://www.jb51.net/article/109382.htm 这篇文章主要介绍了详解如何在CentOS7中使用Nginx和PHP7-FPM安装Nextcloud,会通过 N ...

  8. 详解如何在Laravel中增加自定义全局函数

    http://www.php.cn/php-weizijiaocheng-383928.html 如何在Laravel中增加自定义全局函数?在我们的应用里经常会有一些全局都可能会用的函数,我们应该怎么 ...

  9. 第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法

    第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法 上节介绍了Python中类的静态方法,本节将结合案例详细说明相关内容. 一.    案例说明 本节定义了类Sta ...

随机推荐

  1. 第三篇: 服务消费者(Feign)

    本文根据https://blog.csdn.net/forezp/article/details/81040965写出,修正了部分瑕疵,在此对那位博主表示感谢. 上一篇文章讲述通过RestTempla ...

  2. Git查看远程提交状态的方法

    git使用过程中,经常遇到这样的问题,已经git push 了,但是,由于冲突或者push的分支不对,导致远程的和本地的不一致. 这就需要提交后查看一下远程的是否ok. 查了一下资料,找到了一些方法, ...

  3. .NET手记-JS获取Url参数

    最近为App做活动专区,其中很多活动都是采用html 5页面来制作的.一方面体量较小,制作快速,更新维护容易:另一方面,嵌入App后适配效果也不会很差. 这里我们采用混编形式来从native app传 ...

  4. 阿里P9架构师讲解从单机至亿级流量大型网站系统架构的演进过程

    阶段一.单机构建网站 网站的初期,我们经常会在单机上跑我们所有的程序和软件.此时我们使用一个容器,如tomcat.jetty.jboos,然后直接使用JSP/servlet技术,或者使用一些开源的框架 ...

  5. Centos 7 安装 rabbitmq

    1.安装erlang rabbitmq 官方下载地址 "http://www.rabbitmq.com/download.html" ,选择"RHEL, CentOS, ...

  6. BF算法(模式匹配)

    BF算法 (Brute-Force算法) 一种简单的模式匹配算法,目的是寻找模式串p是否在目标串s中有出现. 思想:先从第一个字符开始匹配,如果p[j]==s[i],那么继续向下比较,一旦不相等,即回 ...

  7. jdk8- list操作

    本文版权归 远方的风lyh和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. student类 public class Student { private String age; ...

  8. 细说spring事务配置属性

    一.spring事务配置 1.spring配置 在配置数据源的下方配置 <!-- 事务配置 --> <bean id="transactionManager" c ...

  9. Ribbon使用Hystrix

    1.导入依赖spring-cloud-starter-hystrix <dependency> <groupId>org.springframework.cloud</g ...

  10. Eclipse Gradle 构建多模块项目

    注意: 1.Eclipse不如IDEA智能,Eclipse建立的Gradle Project项目在目录级别上是同级的; 2.user-web模块如果要引用user-service模块,直接引用是找不到 ...