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 控制包

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

相关推荐
harry235day13 分钟前
Compose 带动画的待办清单列表页
android·android jetpack
vocal13 分钟前
我的安卓第一课:四大组件之一Activity及其组件RecyclerView
android
咕噜企业签名分发-淼淼39 分钟前
如何实现安卓端与苹果端互通的多种方案
android
wu_android1 小时前
Android 线性布局中常见的冲突属性总结
android
恋猫de小郭2 小时前
为什么跨平台框架可以适配鸿蒙,它们的技术原理是什么?
android·前端·flutter
小智学长 | 嵌入式3 小时前
SOC-ESP32S3部分:36-适配自己的板卡
单片机·物联网·esp32
张风捷特烈3 小时前
每日一题 Flutter#5,6 | 两道 Widget 选择题
android·flutter
移动开发者1号3 小时前
App主界面点击与跳转启动方式区别
android·kotlin
移动开发者1号3 小时前
我用Intent传大图片时竟然崩了,怎么回事啊
android·kotlin
打码人的日常分享11 小时前
物联网智慧医院建设方案(PPT)
大数据·物联网·架构·流程图·智慧城市·制造