HarmonyOS鸿蒙Next ArkTS实现MQTT协议

HarmonyOS鸿蒙Next ArkTS实现MQTT协议

介绍

MQTT是物联网中的一种协议,在HarmonyOS API9平台,解决方案以C++库移植为实现方案。

遥遥领先的平台,使用MQTT怎能不遥遥领先呢!

新年快乐,本篇将带领你手把手实现HarmonyOS ArkTS语言的MQTT协议。

准备

效果

Screenshot_20240105094251692.png

HarmonyOS MQTT实现概况

业务流程

页面与功能实现类

MQTT 实现路线

MQTT协议最大的好处是纯软件协议, 不像Zigbee协议还会和硬件相关,所以在实现MQTT协议前,我们只需要专注于两件事情:

  1. MQTT协议传输通道
  2. MQTT协议格式

通道即传输数据的载体,这里指的是Sokect, 了解HarmonyOS平台的Sokect使用方法尤为重要。

数据传输通道打通之后,需要专注于MQTT协议格式的实现。

由于之前对MQTT协议有所了解,所以在HarmonyOS 平台中看到Socket时,觉得在这个新平台上实现MQTT协议理论上没有任何问题,所以最终决定干它。

下边这张图是实现HarmonyOS MQTT协议的过程,仅作参考。

MQTT资深专家,只需要阅读关于HarmonyOS Socket的API 和 TypeScript 操作字节的一些基础内容即可

MQTT协议介绍

一) MQTT共有15种协议

  1. CONNECT
  2. CONNACK
  3. PUBLISH
  4. PUBACK
  5. PUBREC
  6. PUBREL
  7. PUBCOMP
  8. DISCONNECT
  9. PINGREQ
  10. PINGRES
  11. SUBSCRIBE
  12. SUBACK
  13. UNSUBSCRIBE
  14. UNSUBACK
  15. AUTH

二)MQTT共有7种数据格式

这些数据格式名称会在MQTT技术规范中作为标准用语使用

  1. one Byte
  2. Two Byte
  3. Four Byte
  4. UTF-8 String
  5. UTF-8 String Pair
  6. Variable Byte Integer
  7. Binary Data

数据格式实现

数据格式稍微看一下即可

详情可参见MQTT V5.0规范

关于数据格式文档可以查找关键词 “1.5 Data representation”

Two Byte

比如数字2,如果要编码为两个字节,则调用

twoByte(2)

Four Byte

比如数字2,如果要编码为四个字节,则调用

fourByte(2)

UTF-8 String

比如数字2,如果要采用UTF-8编码,则调用

utf8String(2)

UTF-8 String Pair

比如Key为‘Key-Hello’,Value为‘Value-World’如果要采用Key-Value方式的UTF-8编码,则调用

utf8StringPair('Key-Hello','Value-World')

Variable Byte Integer

可变字节编码,这种编码方式的最大长度是4个字节。

所以,用1~4个字节可动态编码相关数字,实现节省占用内存的目标

比如数字2,编码完成后,只会占用一个字节

encodeVariableByteInteger(2)

Binary Data

这种数据格式是由2字节和剩余的字节数组组成,除2个字节数组在解码时,需要按照约定来解码。

比如想要表达数字2,则调用

binaryData(new Uint8Array([2]))

HarmonyOS Socket

HarmonyOS 官方指南

1)包引入

注意:这个包在编译时,DevEco Studio 会提示警告,但官方资料中并未做说明

import socket from '@ohos.net.socket';

2)创建Socket

// 创建一个TCPSocket连接,返回一个TCPSocket对象。
let tcp = socket.constructTCPSocketInstance();

3)注册Socket事件消息

连接事件

接收消息事件

Socket关闭事件

错误事件

tcp.on('message', value => {  
    console.log("on message")  
    let buffer = value.message  
    let dataView = new DataView(buffer)  
    let str = ""
    for (let i = 0; i < dataView.byteLength; ++i) {    
        str += String.fromCharCode(dataView.getUint8(i))  
    }  
    console.log("on connect received:" + str)
});

tcp.on('connect', () => {  
    console.log("on connect")
});

tcp.on('close', () => {  
    console.log("on close")
});

tcp.on('error', () => {  
    console.log("on error")
});

4)绑定本地端口

// 绑定IP地址和端口。
let bindAddress = {
    address: '192.168.xx.xx',
    port: 1234, // 绑定端口,如1234
    family: 1
};
tcp.bind(bindAddress, err => {
    if (err) {
        console.log('bind fail');
        return;
    }
    console.log('bind success');
    
    //TODO 连接服务端代码
    .....
});

5)连接Broker服务器

// 绑定IP地址和端口。
let bindAddress = {
    address: '192.168.xx.xx',
    port: 1234, // 绑定端口,如1234
    family: 1
};
tcp.bind(bindAddress, err => {
    if (err) {
        console.log('bind fail');
        return;
    }
    console.log('bind success');
    
    let connectAddress = {
        address: '192.168.xx.xx',
        port: 5678, // 连接端口,如5678
        family: 1
    };
    tcp.connect({
        address: connectAddress, timeout: 6000
        }, err => {
        if (err) {
            console.log('connect fail');
            return;
        }
    console.log('connect success');

    // 发送数据
    tcp.send({
        data: 'Hello, server!'
       }, err => {
         if (err) {
            console.log('send fail');
            return;
          }
        console.log('send success');
     })
 });
});

MQTT 协议实现一瞥

  • 协议的实现过程,需要对照MQTT V5.0规范逐条实现。
  • 切不可操之过急
  • 发布一条消息和接收一条消息用到的协议都是PUBLISH

CONNECT协议

如下代码即为CONNECT协议实现的源码

Socket通道创建成功之后,仅仅代表客户端与服务端已经建立了消息通道,但这条通道是否可以使用,就需要用到“连接“协议,简单点的讲:客户端和服务端开始通信,交流的规则肯定是一致的。

从如下CONNECT协议实现源码注释中可见,一个通信包包含3个部分:1. 固定头(Fixed Header) 2. 可变头(Variable Header)3. 负载体(PayLoad)

注意:固定头表示由两部分组成,第一部分为一个字节,表示数据包类型和其它预留属性,第二部分表示数据包除第一个字节和自己所占用的字节以外,还剩余多少个字节,用于数据包解码参照计算。第二部分的字节长度数据类型为Variable Byte Integer,因此,其可能占用1~4个字节

总结

按照MQTT V5.0官方文档实现协议,对本人来讲,感觉非常开心,开心的原因回过头来想想,可能就几条吧

  • 做完了一件以前不愿意做的事情
  • 这件事情可造?造。事情本就是一件一件来做的,想做就按照想法做

愿大家2024年,不负时光,行大运,发大财。


更多关于HarmonyOS鸿蒙Next ArkTS实现MQTT协议的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

欢迎大佬开源

更多关于HarmonyOS鸿蒙Next ArkTS实现MQTT协议的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


大佬,这么牛逼的技术,应该搞个专题呀,那样就牛逼了。还有更应该开源,让大伙一起用起来,才能让代码更牛逼,传播更广。遇到奇奇怪怪的问题也会更多。还是想说提一句,果然牛逼

大佬,代码能开源吗?

在HarmonyOS鸿蒙Next中使用ArkTS实现MQTT协议,可以通过集成第三方库如paho-mqttmqtt.js。首先,安装相关依赖,然后在ArkTS中编写代码以建立MQTT连接、订阅主题、发布消息和处理接收到的消息。以下是一个简单的示例代码框架:

import mqtt from 'mqtt';

const client = mqtt.connect('mqtt://broker.hivemq.com');

client.on('connect', () => {
  console.log('Connected to MQTT broker');
  client.subscribe('test/topic', (err) => {
    if (!err) {
      client.publish('test/topic', 'Hello from HarmonyOS');
    }
  });
});

client.on('message', (topic, message) => {
  console.log(`Received message on ${topic}: ${message.toString()}`);
});

确保在项目中正确配置网络权限,并处理连接断开和错误情况。

回到顶部