联系我们
简单又实用的WordPress网站制作教学
当前位置:网站首页 > 程序开发学习 > 正文

Mqtt-Java深入理解有效载荷解析

作者:访客发布时间:2023-10-26分类:程序开发学习浏览:136


导读:前言关于mqtt基础课程系列(HIVEMQ)的[译文]工作已结束,期间有一些术语实在难以翻译为可理解的中文技术用语.为了进一步理解mqtt特性,本篇文章将通过自定义解析有效载荷的方...

前言

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

目标

解析有效负载内容

准备

  1. 参见“mqtt实践”,“mqtt-JAVA连接协议”完成测试工程配置
  2. 代码仓库:githeb.com/harveyBlack…
  3. 协议规范:docs.oASIS-Open.org/mqtt/mqtt/v…

了解有效负载

描述

有些MQTT控制包含一个有效载荷,并把它作为控制包的最后一部分。在发布控制包中,有效负载就是一个应用消息

数据包整体结构

先前文章“mqtt-Java mqtt控制包格式(mqtt控制包格式)”

Mqtt-Java深入理解有效载荷解析

包含有效负载的控制包

控制包名称选项描述
连接必须连接代理服务器(经纪商)
订阅必须订阅主题
子确认必须订阅确认
取消订阅必须解除主题的订阅
取消退货确认必须解除主题的订阅确认
发布可选发布主题

解码有效负载

连接控制包

1.mqtt规范

‘3.1.3连接有效负载’

2.数据结构

  1. 客户端标识符:Will属性:Will主题:Will负载:用户名:密码
  2. 数据类型

想了解mqtt的数据类型,可参见“mqtt-Java数据描述(数据表示)”

  • 客户端ID:UTF-8编码,即:长度(2个字节)+编码内容
  • 遗嘱属性
    • 属性长度:可变字节
    • 将延迟间隔:四字节整数
    • 有效载荷格式指示符:字节
    • 消息过期间隔:四字节整数
    • 内容类型:UTF-8编码
    • 响应主题:UTF-8编码
    • 关联数据:二进制
    • 用户属性:UTF-8字符串对
  • Will主题:UTF-8编码
  • 将负载:二进制
  • 用户名:UTF-8编码
  • 密码:二进制

3.解码流程

根据连接有效负载的结构来讲,共分5大部分,除客户端ID没有前置条件,剩余部分都需要根据控制包头中的连接标志标志来作为前置条件来进行解码。Mqtt-Java深入理解有效载荷解析

4.代码片段

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

/**
* 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);
...

}

订阅控制包

1.mqtt规范

‘3.8.3订阅负载’

2.数据结构

  1. 主题过滤器:订阅选项
  2. 数据类型
    • 主题过滤器:UTF-8编码
    • 订阅选项:字节

3.解码流程

Mqtt-Java深入理解有效载荷解析

4.代码片段

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

/**
* 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++;

}
...

}

取消订阅、发布控制包

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


标签:MQTTJava有效载荷


程序开发学习排行
最近发表
网站分类
标签列表