MQTT-java 深入理解PAYLOAD解析

前言

关于MQTT基础课程系列(HIVEMQ)的【译文】工作已结束,期间有一些术语实在难以翻译为可理解的中文技术用语。为了进一步理解MQTT特性,本篇文章将通过自定义解析PAYLOAD的方式,来解惑分析MQTT规范中特定术语。

目标

解析PAYLOAD内容

准备

  1. 参见 "MQTT 实践" ,"MQTT-Java 连接协议" 完成测试工程配置
  2. 代码仓库:github.com/harveyblack...
  3. 协议规范:docs.oasis-open.org/mqtt/mqtt/v...

了解PAYLOAD

描述

有些MQTT控制包含一个payload, 并把它作为控制包的最后一部分。在PUBLISH控制包中,payload就是一个应用消息

数据包整体结构

先前文章"MQTT-java MQTT控制包格式(MQTT Control Packet format)"

包含PAYLOAD的控制包

控制包名称 选项 描述
CONNECT 必须 连接代理服务器(broker)
SUBSCRIBE 必须 订阅主题
SUBACK 必须 订阅ACK
UNSUBSCRIBE 必须 解除主题的订阅
UNSUBACK 必须 解除主题的订阅ACK
PUBLISH 可选 发布主题

解码PAYLOAD

CONNECT 控制包

1. MQTT规范

'3.1.3 CONNECT Payload'

2. 数据结构

  1. Client Identifier : Will Properties : Will Topic : Will Payload : User Name : Password
  2. 数据类型

想了解MQTT的数据类型,可参见"MQTT-java 数据描述(Data representation)"

  • ClientID : UTF-8 Encoded, 即:长度(2个字节)+ 编码内容
  • Will Properties
    • Property Length : Variable Byte
    • Will Delay Interval: Four Byte Integer
    • Payload Format Indicator: Byte
    • Message Expiry Interval: Four Byte Integer
    • Content Type : UTF-8 Encoded
    • Response Topic : UTF-8 Encoded
    • Correlation Data : Binary
    • User Property : UTF-8 String Pair
  • Will Topic : UTF-8 Encoded
  • Will Payload : Binary
  • User Name : UTF-8 Encoded
  • Password : Binary

3. 解码流程

根据CONNECT payload的结构来讲,共分5大部分,除ClientID没有前置条件,剩余部分都需要根据控制包头中的CONNECT Flags标志来作为前置条件来进行解码。

4. 代码片段

实验代码入口文件ExampleParsePayLoad.java

详细解析过程参见代码库中的HarveyDebug.java文件,方法名为:parsePayload()

ini 复制代码
/**
* header : 固定头和可变头
**/
public static void parsePayload(byte [] header, byte [] payload){

...

//3.1.3.1 Client Identifier (ClientID)
int payloadIndex = 0;
int clientIdentifierLength = (payload[payloadIndex] << 8)&0xff00 | payload[payloadIndex+1];

byte [] clientIdentifierB = new byte[clientIdentifierLength];
for(int k = 0; k < clientIdentifierLength; k++){
    clientIdentifierB[k] = payload[payloadIndex + k];
}

payloadIndex = payloadIndex + clientIdentifierLength;

String clientIdentifier = new String(clientIdentifierB, StandardCharsets.UTF_8);
d("Client Identifier: " + clientIdentifier);
...

}

SUBSCRIBE 控制包

1. MQTT规范

'3.8.3 SUBSCRIBE Payload'

2. 数据结构

  1. Topic Filter : Subscription Options
  2. 数据类型
    • Topic Filter : UTF-8 Encoded
    • Subscription Options : Byte

3. 解码流程

4. 代码片段

实验代码入口文件ExampleParsePayLoad.java

详细解析过程参见代码库中的HarveyDebug.java文件,方法名为:parsePayload()

ini 复制代码
/**
* header : 固定头和可变头
**/
public static void parsePayload(byte [] header, byte [] payload){

...

int payloadIndex = 0;

while (payloadIndex < payload.length) {

    {
        int willTopicLength = (payload[payloadIndex++] << 8) & 0xff00 | payload[payloadIndex++];
        byte[] willTopicB = new byte[willTopicLength];
        for (int k = 0; k < willTopicLength; k++) {
            willTopicB[k] = payload[payloadIndex + k];
        }
        payloadIndex = payloadIndex + willTopicLength;

        String contentType = new String(willTopicB, StandardCharsets.UTF_8);
        d("Topic Filters: " + contentType);
    }

    //Reserved Retain Handling RAP NL QoS
    String Reserved = ((payload[payloadIndex] & 0xc0) >> 6) + "";
    String RetainHandling = ((payload[payloadIndex] & 0x30) >> 4) + "";
    String RAP = ((payload[payloadIndex] & 0x8) >> 3) + "";
    String NL = ((payload[payloadIndex] & 0x4) >> 2) + "";
    String QoS = (payload[payloadIndex] & 0x3) + "";

    d("Reserved:" + Reserved + " , " + "RetainHandling:" + RetainHandling + " , " + "RAP:" + RAP + " , " + "NL:" + NL + " , " + "QoS:" + QoS);

    payloadIndex++;

}
...

}

SUBACK,UNSUBSCRIBE,UNSUBACK,PUBLISH 控制包

依据本篇文章前两个类型的分析过程和实验代码,可自行尝试解码一下控制包

相关推荐
lichong9515 小时前
Android studio 修改包名
android·java·前端·ide·android studio·大前端·大前端++
小莞尔8 小时前
【51单片机】【protues仿真】基于51单片机电压测量多量程系统
c语言·单片机·嵌入式硬件·物联网·51单片机
爱学习的大牛1238 小时前
MVVM 架构 android
android·mvvm
TDengine (老段)9 小时前
TDengine 数学函数 FLOOR 用户手册
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据
alexhilton10 小时前
理解retain{}的内部机制:Jetpack Compose中基于作用域的状态保存
android·kotlin·android jetpack
꒰ঌ 安卓开发໒꒱11 小时前
Mysql 坏表修复
android·mysql·adb
_李小白11 小时前
【Android Gradle学习笔记】第八天:NDK的使用
android·笔记·学习
袁震11 小时前
Android-Compose 列表组件详解
android·recyclerview·compose
兆龙电子单片机设计12 小时前
【STM32项目开源】STM32单片机智能家居控制系统
stm32·单片机·物联网·开源·毕业设计·智能家居
2501_9160074712 小时前
提升 iOS 26 系统流畅度的实战指南,多工具组合监控
android·macos·ios·小程序·uni-app·cocoa·iphone