MQTT协议实现Eclipse Paho学习总结
MQTT协议实现Eclipse Paho学习总结
摘自:https://www.cnblogs.com/yfliufei/p/4383852.html
2015-04-01 14:57 by 辣椒酱, 4278 阅读, 0 评论, 收藏, 编辑
一、概述
遥测传输 (MQTT) 是轻量级基于代理的发布/订阅的消息传输协议,设计思想是开放、简单、轻量、易于实现。这些特点使它适用于受限环境。例如,但不仅限于此:
- 网络代价昂贵,带宽低、不可靠。
- 在嵌入设备中运行,处理器和内存资源有限。
该协议的特点有:
- 使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合。
- 对负载内容屏蔽的消息传输。
- 使用 TCP/IP 提供网络连接。
- 有三种消息发布服务质量:
- “至多一次”,消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。
- “至少一次”,确保消息到达,但消息重复可能会发生。
- “只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。
- 小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量。
- 使用 Last Will 和 Testament 特性通知有关各方客户端异常中断的机制。
二、MQTT协议实现Eclipse Paho
三、MQTT协议的报文类别
3.1 MQTT协议规定报文
当一个从客户端到服务器的TCP/IP套接字连接被建立时,必须用一个连接流来创建一个协议级别的会话。
连接请求确认报文(CONNECTACK)是服务器发给客户端,用以确认客户端的连接请求
客户端发布报文到服务器端,用来提供给有着不同需求的订阅者们。每个发布的报文都有一个主题,这是一个分层的命名空间,他定义了报文来源分类,方便订阅者订阅他们需要的主题。订阅者们可以注册自己的需要的报文类别。
发布确认报文(PUBACK)是对服务质量级别为1的发布报文的应答。他可以是服务器对发布报文的客户端的报文确认,也可以是报文订阅者对发布报文的服务器的应答。
PUBREC报文是对服务质量级别为2的发布报文的应答。这是服务质量级别为2的协议流的第二个报文。PUBREC是由服务器端对发布报文的客户端的应答,或者是报文订阅者对发布报文的服务器的应答。
PUBREL是报文发布者对来自服务器的PUBREC报文的确认,或者是服务器对来自报文订阅者的PUBREC报文的确认。它是服务质量级别为2的协议流的第三个报文。
PUBCOMP报文是服务器对报文发布者的PUBREL报文的应答,或者是报文订阅者对服务器的PUBREL报文的应答。它是服务质量级别为2的协议流的第四个也是最后一个报文。
订阅报文(SUBSCRIBE)允许一个客户端在服务器上注册一个或多个感兴趣的主题名字。发布给这些主题的报文作为发布报文从服务器端交付给客户端。订阅报文也描述了订阅者想要收到的发布报文的服务质量等级。
当服务器收到客户端发来的订阅报文时,将发送订阅报文的确认报文给客户端。一个这样的确认报文包含一列被授予的服务质量等级。被授予的服务质量等级次序和对应的订阅报文中的主题名称的次序相符。
退订主题的报文是从客户端发往服务器端,用以退订命名的主题。
退订确认报文是从服务器发往客户端,用以确认客户端发来的退订请求报文。
Ping请求报文是从连接的客户端发往服务器端,用来询问服务器端是否还存在。
Ping应答报文是从服务器端发往Ping请求的客户端,对客户端的Ping请求进行确认。
14. 断开通知(DISCONNECT)
断开通知报文是从客户端发往服务器端用来指明将要关闭它的TCP/IP连接,他允许彻底地断开,而非只是下线。如果客户端已经和干净会话标志集联系,那么所有先前关于客户端维护的信息将被丢弃。一个服务器在收到断开报文之后,不能依赖客户端关闭TCP/IP连接。
3.2 Eclipse Paho的对报文的实现
3.3 心跳包
- public class MqttPingReq extends MqttWireMessage {
- public MqttPingReq() {
- super(MqttWireMessage.MESSAGE_TYPE_PINGREQ);
- }
- /**
- * Returns <code>false</code> as message IDs are not required for MQTT
- * PINGREQ messages.
- */
- public boolean isMessageIdRequired() {
- return false;
- }
- protected byte[] getVariableHeader() throws MqttException {
- return new byte[0];
- }
- protected byte getMessageInfo() {
- return 0;
- }
- public String getKey() {
- return new String("Ping");
- }
- }
- /**
- * Writes an <code>MqttWireMessage</code> to the stream.
- */
- public void write(MqttWireMessage message) throws IOException, MqttException {
- byte[] bytes = message.getHeader();
- byte[] pl = message.getPayload();
- // out.write(message.getHeader());
- // out.write(message.getPayload());
- out.write(bytes,0,bytes.length);
- out.write(pl,0,pl.length);
- }
哦,这下好了,原来,其发送的是header和payload,然后,我们就可以看心跳包的header和payload是什么。
- protected byte[] getVariableHeader() throws MqttException {
- return new byte[0];
- }
这个方法,我们就知道了,这个肯定是父类MqttWireMessage中getHeader调用的方法,然后再回到MqttWireMessage,果真getHeader方法如下:
- public byte[] getHeader() throws MqttException {
- if (encodedHeader == null) {
- try {
- int first = ((getType() & 0x0f) << 4) ^ (getMessageInfo() & 0x0f);
- byte[] varHeader = getVariableHeader();
- int remLen = varHeader.length + getPayload().length;
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- DataOutputStream dos = new DataOutputStream(baos);
- dos.writeByte(first);//1个字节
- dos.write(encodeMBI(remLen));//1个字节
- dos.write(varHeader);//0个字节
- dos.flush();
- encodedHeader = baos.toByteArray();
- } catch(IOException ioe) {
- throw new MqttException(ioe);
- }
- }
- return encodedHeader;
- }
而MqttWireMessage中还有一个getPayload方法,这个方法MqttPingReq 没有重写,也就是说,默认调用这个方法。
- /**
- * Sub-classes should override this method to supply the payload bytes.
- */
- public byte[] getPayload() throws MqttException {
- return new byte[0];//0个字节
- }
也就是说MQTT的心跳包只有2个字节!
MQTT协议实现Eclipse Paho学习总结的更多相关文章
- MQTT协议实现Eclipse Paho学习总结二
一.概述 前一篇博客(MQTT协议实现Eclipse Paho学习总结一) 写了一些MQTT协议相关的一些概述和其实现Eclipse Paho的报文类别,同时对心跳包进行了分析.这篇文章,在不涉及MQ ...
- [3] MQTT,mosquitto,Eclipse Paho---怎样使用 Eclipse Paho MQTT工具来发送订阅MQTT消息?
在上两节,笔者主要介绍了 MQTT,mosquitto,Eclipse Paho的基本概念已经怎样安装mosquitto. 在这个章节我们就来看看怎样用 Eclipse Paho MQTT工具来发送接 ...
- 采用MQTT协议实现android消息推送(2)MQTT服务端与客户端软件对比、android客户端示列表
1.服务端软件对比 https://github.com/mqtt/mqtt.github.io/wiki/servers 名称(点名进官网) 特性 简介 收费 支持的客户端语言 IBM MQ 完整的 ...
- MQTT协议通俗讲解
参考 Reference v3.1.1 英文原版 中文翻译版 其他资源 网站 MQTT官方主页 Eclipse Paho 项目主页 测试工具 MQTT Spy(基于JDK) Chrome插件 MQTT ...
- 基于RabbitMQ的MQTT协议及应用
MQTT的开源代码地址先贴在这里:https://github.com/mqtt/mqtt.github.io/wiki/servers MQTT定义: MQTT(Message Queuing Te ...
- mqtt协议实现 java服务端推送功能(二)java demo测试
上一篇写了安装mosQuitto和测试,但是用cmd命令很麻烦,有没有一个可视化软件呢? 有,需要在google浏览器下载一个叫MQTTLens的插件 打开MQTTLens后界面如下: 打开conne ...
- MQTT 协议学习: 总结 与 各种定义的速查表
背景 经过几天的学习与实操,对于MQTT(主要针对 v3.1.1版本)的学习告一段落,为了方便日后的查阅 本文链接:<MQTT 协议学习: 总结 与 各种定义的速查表> 章节整理 MQTT ...
- MQTT 协议学习:000-有关概念入门
背景 从本章开始,在没有特殊说明的情况下,文章中的MQTT版本均为 3.1.1. MQTT 协议是物联网中常见的协议之一,"轻量级物联网消息推送协议",MQTT同HTTP属于第七层 ...
- 【转载】MQTT学习笔记——MQTT协议体验 Mosquitto安装和使用
http://blog.csdn.net/xukai871105/article/details/39252653 0 前言 MQTT是IBM开发的一个即时通讯协议.MQTT是面向M2M和物联 ...
随机推荐
- 黄聪:WordPress默认编辑器可视化切换不见了,非插件导致消失问题
1.后台---用户---我的个人资料 2.看看 [可视化编辑器]的[撰写文章时不使用可视化编辑器]项目是不是勾上了 3.去掉保存即可
- mydumper 找不到libmysqlclient.so.20
报错信息: mydumper: error while loading shared libraries: libmysqlclient.so.20: cannot open shared objec ...
- lamp环境应用实践
LAMP之apache2.4.33 apache工作模式 apache 常用工作模式有2种,区别在于 worker模式 1. 线程模式 2. 占用资源少 3. 稳定性略差 4. 并发大 prefork ...
- SET STATISTICS IO
SET STATISTICS IO (Transact-SQL) https://technet.microsoft.com/zh-cn/library/ms184361(SQL.90).aspx 如 ...
- Cocos开发前准备
Cocos2d-HTML5( http://www.cocos2d-x.org )引擎 代码编辑器:webstorm (http://www.jetbrains.com/)+ Sublime Text ...
- django之上传图片
上传图片 当Django在处理文件上传的时候,文件数据被保存在request.FILES FILES中的每个键为<input type="file" name="& ...
- TCP的交互数据流
在TCP进行数据传输时,可以分为成块数据流和交互数据流两种,如果按字节计算,成块数据与交互数据的比例约为90%和10%,TCP需要同时处理这两类数据,且处理的算法不同. 书籍本章中以Rlogin应用为 ...
- leetcode278
/* The isBadVersion API is defined in the parent class VersionControl. bool IsBadVersion(int version ...
- __slots__
__slots__ 由于Python是动态语言,任何实例在运行期都可以动态地添加属性. 如果要限制添加的属性,例如,Student类只允许添加 name.gender和score 这3个属性,就可以利 ...
- 关于Web项目出现懒加载异常的解决方案
manytomany关系中,使用 fetch = FetchType.LAZY 来做懒加载,加快些性能.但是却一直出错,原因是session被关闭,要保持session,需要事务. Hibernate ...