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

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

相关推荐
coderzxy10 小时前
mbpoll 交叉编译
物联网
Doro再努力10 小时前
【Linux操作系统10】Makefile深度解析:从依赖推导到有效编译
android·linux·运维·服务器·编辑器·vim
Daniel李华10 小时前
echarts使用案例
android·javascript·echarts
中议视控11 小时前
可编程网络中央控制系统主机通过红外发射棒控制空调电视等红外设备
网络·物联网·5g
星马梦缘11 小时前
EDA彩灯电路绘制
单片机·嵌入式硬件·物联网·pcb·eda·嘉立创
做人不要太理性11 小时前
CANN Runtime 运行时组件深度解析:任务调度机制、存储管理策略与维测体系构建逻辑
android·运维·魔珐星云
我命由我1234512 小时前
Android 广播 - 静态注册与动态注册对广播接收器实例创建的影响
android·java·开发语言·java-ee·android studio·android-studio·android runtime
朗迹 - 张伟12 小时前
Tauri2 导出 Android 详细教程
android
lpruoyu13 小时前
【Android第一行代码学习笔记】Android架构_四大组件_权限_持久化_通知_异步_服务
android·笔记·学习
独自破碎E14 小时前
【BISHI15】小红的夹吃棋
android·java·开发语言