HarmonyOS 鸿蒙Socket小试MQTT连接

发布于 1周前 作者 phonegap100 最后一次编辑是 5天前 来自 鸿蒙OS

HarmonyOS 鸿蒙Socket小试MQTT连接


介绍

本篇分享一下 HarmonyOS 中的Socket使用方法

将从2个方面实践:

  1. HarmonyOS 手机应用连接PC端 SocketServer
  2. HarmonyOS 手机应用连接MQTT 服务端

通过循序渐进的方式,全面了解实践HarmonyOS中的Socket用法

Socket官方指导

注意:编译时IDE会给出如下警告提示,@ohos.net.socket 这个包没有验证过。

Currently module for ‘@ohos.net.socket’ is not verified. If you’re importing napi, its verification will be enabled in later SDK version. Please make sure the corresponding .d.ts file is provided and the napis are correctly declared.

官方文档说明

引入Socket包

import socket from ‘[@ohos](/user/ohos).net.socket’;

创建TCPSocket,连接远端服务器

//注意,这里声明变量tcp, 建议将类型加上,否则不利于IDE联想API
let tcp: socket.TCPSocket = socket.constructTCPSocketInstance();

let bindAddress = {
address: ‘192.168.xx.xx’,
port: x
};


let connectAddress = {
address: ‘192.168.xx.xx’,
port: x
};


//1. 绑定本机地址和端口
tcp.bind(bindAddress, err => {


if(err){
console.log(‘1-’ + JSON.stringify(err))
return
}


//2. 连接远端服务器
tcp.connect({
address: connectAddress,
timeout: 30000
}).then( r => {
console.log(‘2-’ +JSON.stringify®)
}).catch((e) => {
console.log(‘3-’ + JSON.stringify(e))
})


})

状态监听

订阅“连接”

tcp.on(‘connect’, () => {

});

解除“连接”订阅

tcp.off(‘connect’, () => {

});

订阅“消息”

tcp.on(‘message’, () => {
//即:可以在这里随时接收到服务端发送过来的消息
});

解除“消息”订阅

tcp.off(‘message’, () => {

});

发送消息

let msg: string = ‘我是HarmonyOS客户端’

tcp.send({data: msg}, (error)=>{
if(error) {
console.log('消息没有发送成功: ’ + JSON.stringify(error))
} else {
console.log(‘消息发送成功’)
}
})

实践:实现Socket与ServerSocket通信

创建ServerSocket 服务

这里使用IntelliJ IDEA创建一个Java工程,然后运行在自己电脑上即可使用

如果你实在没法自己实现ServerSocket,可以在网上找一个调试Socket的工具

监听客户端接入

package com.harvey.socketserver;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;


public class Main {


public static <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> main(<span class="hljs-built_in"><span class="hljs-built_in">String</span></span>[] args) {
        <span class="hljs-keyword"><span class="hljs-keyword">try</span></span> {
            ServerSocket serverSocket = <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> ServerSocket(<span class="hljs-number"><span class="hljs-number">6666</span></span>);

            <span class="hljs-comment"><span class="hljs-comment">//一. 建立客户端监听</span></span>
            <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> Thread(<span class="hljs-keyword"><span class="hljs-keyword">new</span></span> Runnable() {
                @Override
                public <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> run() {
                    <span class="hljs-keyword"><span class="hljs-keyword">while</span></span> (<span class="hljs-literal"><span class="hljs-literal">true</span></span>){
                        <span class="hljs-keyword"><span class="hljs-keyword">try</span></span> {
                            Socket clientSocket = serverSocket.accept();

                            System.out.println(<span class="hljs-string"><span class="hljs-string">"客户端:"</span></span> + clientSocket.getInetAddress().getLocalHost()+<span class="hljs-string"><span class="hljs-string">"已连接到服务器"</span></span>);

                            <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> Server(clientSocket).start();

                        } <span class="hljs-keyword"><span class="hljs-keyword">catch</span></span> (IOException e) {
                            e.printStackTrace();
                        }
                        <span class="hljs-keyword"><span class="hljs-keyword">try</span></span> {
                            Thread.sleep(<span class="hljs-number"><span class="hljs-number">1000</span></span>);
                        } <span class="hljs-keyword"><span class="hljs-keyword">catch</span></span> (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();

        } <span class="hljs-keyword"><span class="hljs-keyword">catch</span></span> (IOException e) {
            e.printStackTrace();
        }
}
}

监听客户端消息且自动回复

package com.harvey.socketserver;

import java.io.*;
import java.net.Socket;


public class Server extends Thread{


Socket clientSocket;
InputStream is;
OutputStream os;
<span class="hljs-built_in"><span class="hljs-built_in">String</span></span> lastReceiverMessage;

int LIVE_TIME = <span class="hljs-number"><span class="hljs-number">60</span></span>*<span class="hljs-number"><span class="hljs-number">1000</span></span>;

public Server(Socket clientSocket){
    <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.clientSocket = clientSocket;
    <span class="hljs-keyword"><span class="hljs-keyword">try</span></span> {
        is = <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.clientSocket.getInputStream();
        os = <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.clientSocket.getOutputStream();
    } <span class="hljs-keyword"><span class="hljs-keyword">catch</span></span> (IOException e) {
        e.printStackTrace();
    }
}

@Override
public <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> run() {

    <span class="hljs-keyword"><span class="hljs-keyword">while</span></span>(LIVE_TIME != <span class="hljs-number"><span class="hljs-number">0</span></span>){

        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> ( <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.clientSocket != <span class="hljs-literal"><span class="hljs-literal">null</span></span> ) {

            <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> ( <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.clientSocket.isClosed() || <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.clientSocket.isInputShutdown() || <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.clientSocket.isOutputShutdown()) {
                LIVE_TIME = <span class="hljs-number"><span class="hljs-number">0</span></span>;
            } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> {
                readMessage();

                responseMessage();

                <span class="hljs-keyword"><span class="hljs-keyword">try</span></span> {
                    Thread.sleep(<span class="hljs-number"><span class="hljs-number">1000</span></span>);
                } <span class="hljs-keyword"><span class="hljs-keyword">catch</span></span> (InterruptedException e) {
                    e.printStackTrace();
                }

                LIVE_TIME -= <span class="hljs-number"><span class="hljs-number">1000</span></span>;
            }

        } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> {
            LIVE_TIME = <span class="hljs-number"><span class="hljs-number">0</span></span>;
        }

    }

    closeAllChannel();

}

<span class="hljs-comment"><span class="hljs-comment">//释放资源</span></span>
private <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> closeAllChannel(){
    <span class="hljs-keyword"><span class="hljs-keyword">try</span></span> {
        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(clientSocket != <span class="hljs-literal"><span class="hljs-literal">null</span></span>){
            clientSocket.close();
            clientSocket = <span class="hljs-literal"><span class="hljs-literal">null</span></span>;
        }
        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(is != <span class="hljs-literal"><span class="hljs-literal">null</span></span>){
            is.close();
            is = <span class="hljs-literal"><span class="hljs-literal">null</span></span>;
        }
        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(os != <span class="hljs-literal"><span class="hljs-literal">null</span></span>){
            os.close();
            os = <span class="hljs-literal"><span class="hljs-literal">null</span></span>;
        }
    } <span class="hljs-keyword"><span class="hljs-keyword">catch</span></span> (IOException e) {
        e.printStackTrace();
    }
}

<span class="hljs-comment"><span class="hljs-comment">//读取客户端消息, 注意:这里是为了省事,用的readLine接口</span></span>
<span class="hljs-comment"><span class="hljs-comment">//如果消息中有换行符,则会丢失消息</span></span>
private <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> readMessage(){

    BufferedReader br = <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> BufferedReader(<span class="hljs-keyword"><span class="hljs-keyword">new</span></span> InputStreamReader(is));
    <span class="hljs-keyword"><span class="hljs-keyword">try</span></span> {
        lastReceiverMessage  = br.readLine();
        System.out.println(<span class="hljs-string"><span class="hljs-string">"已接收到端消息:【"</span></span> + lastReceiverMessage +<span class="hljs-string"><span class="hljs-string">"】"</span></span>);
    } <span class="hljs-keyword"><span class="hljs-keyword">catch</span></span> (IOException e) {
        System.err.println(<span class="hljs-string"><span class="hljs-string">"接收消息失败:"</span></span> + e.getMessage());
    }

}

<span class="hljs-comment"><span class="hljs-comment">//自动回复客户端消息</span></span>
private <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> responseMessage(){
    <span class="hljs-keyword"><span class="hljs-keyword">try</span></span> {
        BufferedWriter bw = <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> BufferedWriter(<span class="hljs-keyword"><span class="hljs-keyword">new</span></span> OutputStreamWriter(clientSocket.getOutputStream()));
        bw.write(System.currentTimeMillis() + <span class="hljs-string"><span class="hljs-string">"亲爱的客户端,已收到您的来信。"</span></span>  +  lastReceiverMessage + <span class="hljs-string"><span class="hljs-string">"\n"</span></span>);
        bw.flush();
        System.out.println(<span class="hljs-string"><span class="hljs-string">"回复消息成功"</span></span>);
    } <span class="hljs-keyword"><span class="hljs-keyword">catch</span></span> (IOException e) {
        System.err.println(<span class="hljs-string"><span class="hljs-string">"回复消息失败:"</span></span> + e.getMessage());
    }

}
}

创建客户端应用

布局

为了验证Socket,交互页面包含如下功能:

  1. 连接/断开
  2. 渲染接收到的消息
  3. 渲染已发送的消息
  4. 文字输入
  5. 消息发送

HarmonyOS 核心代码

import socket from ‘[@ohos](/user/ohos).net.socket’
import util from ‘[@ohos](/user/ohos).util’;
import Prompt from ‘@system.prompt’;

let tcpSocket: socket.TCPSocket = null


@Entry
@Component
struct SocketPage {


@State isConnected: boolean = false


@State sendMessage: string = ‘’
@State inputMessage: string = ‘’
@State receiveMessage: string = ‘’


@State connectButtonBGColor: Color = Color.Gray
@State connectButtonTextColor: Color = Color.White


//页面创建时,注册自定义消息,监听来消息和连接状态
aboutToAppear(){


getContext().eventHub.on(<span class="hljs-string"><span class="hljs-string">'remotemsg'</span></span>, (value)=&gt;{
    <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.receiveMessage = value
})

getContext().eventHub.on(<span class="hljs-string"><span class="hljs-string">'connectStatus'</span></span>, (value)=&gt;{
    <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(value === <span class="hljs-string"><span class="hljs-string">'connect'</span></span>){
      <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.connectButtonBGColor = Color.Green
    } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(value === <span class="hljs-string"><span class="hljs-string">'close'</span></span>){
      <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.connectButtonBGColor = Color.Gray
    }
})
}


//页面销毁时,解除所有订阅,关闭socket
aboutToDisappear() {
tcpSocket.off(“message”)
tcpSocket.off(“connect”)
tcpSocket.off(“close”)
tcpSocket.close()
tcpSocket = null
}
build(){


    Column( {space: <span class="hljs-number"><span class="hljs-number">20</span></span>} ){

      Row( {space: <span class="hljs-number"><span class="hljs-number">20</span></span>} ){
        Button(<span class="hljs-string"><span class="hljs-string">'连接'</span></span>).width(<span class="hljs-number"><span class="hljs-number">60</span></span>).height(<span class="hljs-number"><span class="hljs-number">60</span></span>).fontSize(<span class="hljs-number"><span class="hljs-number">12</span></span>)
          .backgroundColor(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.connectButtonBGColor)
          .fontColor(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.connectButtonTextColor)
          .onClick( ()=&gt; {
            
            <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.isConnected){
              tcpSocket.close()
            } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> {
              connectServer()
            }
            
          })
      }

      Column({space: <span class="hljs-number"><span class="hljs-number">30</span></span>}){
        Text(<span class="hljs-string"><span class="hljs-string">'发送:'</span></span> + <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.sendMessage).fontSize(<span class="hljs-number"><span class="hljs-number">20</span></span>).width(<span class="hljs-string"><span class="hljs-string">'100%'</span></span>)
        Text(<span class="hljs-string"><span class="hljs-string">'接收:'</span></span> + <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.receiveMessage).fontSize(<span class="hljs-number"><span class="hljs-number">20</span></span>).width(<span class="hljs-string"><span class="hljs-string">'100%'</span></span>)
      }.backgroundColor(Color.Pink)
      .padding( { top: <span class="hljs-number"><span class="hljs-number">20</span></span>, bottom: <span class="hljs-number"><span class="hljs-number">20</span></span>} )

      Row({space: <span class="hljs-number"><span class="hljs-number">10</span></span>}) {
        TextArea({placeholder: <span class="hljs-string"><span class="hljs-string">'输入文字'</span></span>, text: <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.inputMessage})
          .onChange( (value) =&gt; {
            <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.inputMessage = value
          })
          .fontSize(<span class="hljs-number"><span class="hljs-number">20</span></span>)
          .width(<span class="hljs-string"><span class="hljs-string">'75%'</span></span>)

        Button(<span class="hljs-string"><span class="hljs-string">'发送'</span></span>).fontColor(<span class="hljs-number"><span class="hljs-number">29</span></span>).onClick( () =&gt; {
          sendMessage(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.inputMessage)
          <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.sendMessage = <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.inputMessage
          <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.inputMessage = <span class="hljs-string"><span class="hljs-string">''</span></span>
        }).width(<span class="hljs-string"><span class="hljs-string">'20%'</span></span>)
      }
      .width(<span class="hljs-string"><span class="hljs-string">'100%'</span></span>)
      .justifyContent(FlexAlign.Center)

    }
    .width(<span class="hljs-string"><span class="hljs-string">'100%'</span></span>)
    .height(<span class="hljs-string"><span class="hljs-string">'100%'</span></span>)
    .alignItems(HorizontalAlign.Start)
    .justifyContent(FlexAlign.Start)
    .padding({top: px2vp(<span class="hljs-number"><span class="hljs-number">120</span></span>)})
}
}


//发送消息
function sendMessage(msg: string){
if(tcpSocket){
tcpSocket.send({data: msg + ‘\n’}, (error)=>{
if(error) {
console.log('消息没有发送成功: ’ + JSON.stringify(error))
} else {


    getContext().eventHub.emit(<span class="hljs-string"><span class="hljs-string">''</span></span>)
    console.log(<span class="hljs-string"><span class="hljs-string">'消息发送成功'</span></span>)
  }
})
} else {
Prompt.showToast({message: ‘还没有连接服务器’})
}
}


//开始连接服务器
function connectServer(){


let bindAddress = {
address: ‘192.168.71.66’,
port: 1983,
family: 1
};


let connectAddress = {
address: ‘192.168.71.23’,
port: 6666 //端口号要和ServerSocket 一致
};


tcpSocket = socket.constructTCPSocketInstance()


tcpSocket.on(‘close’, () => {
console.log(“on close”)
getContext().eventHub.emit(‘connectStatus’, ‘close’)
});


tcpSocket.on(‘connect’, () => {
console.log(“on connect”)
getContext().eventHub.emit(‘connectStatus’, ‘connect’)
});


tcpSocket.on(‘message’ , ( value: {message: ArrayBuffer, remoteInfo: socket.SocketRemoteInfo} ) => {


<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> view = <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> <span class="hljs-built_in"><span class="hljs-built_in">Uint8Array</span></span>(value.message);
<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> textDecoder = util.TextDecoder.create()
<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> str = textDecoder.decodeWithStream(view);

getContext().eventHub.emit(<span class="hljs-string"><span class="hljs-string">'remotemsg'</span></span>, str)
})


tcpSocket.bind(bindAddress, err => {


<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(err){
  console.log(<span class="hljs-string"><span class="hljs-string">'1-'</span></span> + <span class="hljs-built_in"><span class="hljs-built_in">JSON</span></span>.stringify(err))
  <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
}

tcpSocket.connect({
  address: connectAddress,
  timeout: <span class="hljs-number"><span class="hljs-number">30000</span></span>
}).then( r =&gt; {
  console.log(<span class="hljs-string"><span class="hljs-string">'2-'</span></span> +<span class="hljs-built_in"><span class="hljs-built_in">JSON</span></span>.stringify(r))
}).catch((e) =&gt; {
  console.log(<span class="hljs-string"><span class="hljs-string">'3-'</span></span> + <span class="hljs-built_in"><span class="hljs-built_in">JSON</span></span>.stringify(e))
})
})


}

最终效果

实践:实现MQTT连接

准备MQTT Broker

MQTT使用的是 mosquitto,官网下载地址

关于MQTT的入门使用,可参见“MQTT试用

注意:mosquitto 安装完成后,需要打开匿名设置,并且监听自己电脑的IP和1883端口 mosquitto的配置文件名:mosquitto.conf

MQTT 5.0 网址

https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.pdf

  1. 熟悉 “3.1 CONNECT – Connection Request”
  2. 熟悉 “3.2 CONNACK – Connect acknowledgement” 

场景模拟

客户端使用Socket 连接mosquitto, 并且响应连接ACK

代码实现

请求连接

这部分需要分为两步:1. Socket连接 2. MQTT连接请求(即发送连接请求命令)

a. Socket连接

function connectMQTTServer(){

let bindAddress = {
address: ‘192.168.71.66’,
port: 1983,
family: 1
};


let connectAddress = {
address: ‘192.168.71.23’, //MQTT服务器IP
port: 1883 //MQTT服务器端口
};


tcpSocket = socket.constructTCPSocketInstance()


listenerStatus()


tcpSocket.bind(bindAddress, err => {


<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(err){
  console.log(<span class="hljs-string"><span class="hljs-string">'1-'</span></span> + <span class="hljs-built_in"><span class="hljs-built_in">JSON</span></span>.stringify(err))
  <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
}

tcpSocket.connect({
  address: connectAddress,
  timeout: <span class="hljs-number"><span class="hljs-number">30000</span></span>
}).then( r =&gt; {
  console.log(<span class="hljs-string"><span class="hljs-string">'2-'</span></span> +<span class="hljs-built_in"><span class="hljs-built_in">JSON</span></span>.stringify(r))
}).catch((e) =&gt; {
  console.log(<span class="hljs-string"><span class="hljs-string">'3-'</span></span> + <span class="hljs-built_in"><span class="hljs-built_in">JSON</span></span>.stringify(e))
})
})
}

b. MQTT连接请求

tcpSocket.on(‘connect’, () => {
console.log(“on connect”)

//拼接MQTT请求数据
let connectCMD = MQTTConnect.getFixHeader()


//发送MQTT连接请求命令
tcpSocket.send({data: connectCMD.buffer}, (error)=>{
if(error) {
console.log('消息没有发送成功: ’ + JSON.stringify(error))
} else {
console.log(‘消息发送成功’)
}
})


getContext().eventHub.emit(‘connectStatus’, ‘connect’)
});

构建MQTT请求连接数据

代码有点枯燥,都是要对着MQTT 5.0规范文档来实现的

import util from ‘[@ohos](/user/ohos).util’

export default class MQTTConnect{


//3.1.1 CONNECT Fixed Header 【2字节】
//3.1.2 CONNECT Variable Header
//3.1.2.1 Protocol Name 【6字节】
//3.1.2.2 Protocol Version 【1字节】
//3.1.2.3 Connect Flags 【1字节】
//3.1.2.10 Keep Alive 【2字节】
//3.1.2.11 CONNECT Properties
//3.1.2.11.1 Property Length 【1字节】
//3.1.2.11.2 Session Expiry Interval 【4字节】
//3.1.2.11.3 Receive Maximum 【2字节】
//3.1.2.11.4 Maximum Packet Size 【4字节】
//3.1.2.11.5 Topic Alias Maximum 【2字节】
//3.1.2.11.6 Request Response Information 【1字节】
//3.1.2.11.7 Request Problem Information 【1字节】
//3.1.2.11.8 User Property【UTF-8 String Pair】
//3.1.2.11.9 Authentication Method 【UTF-8 String】
//3.1.2.11.10 Authentication Data【Binary Data】
//3.1.3 CONNECT Payload
//3.1.3.1 Client Identifier (ClientID) 【UTF-8 String】
//3.1.3.2 Will Properties
//3.1.3.2.1 Property Length 【Variable Byte Integer】
//3.1.3.2.2 Will Delay Interval 【4字节】
//3.1.3.2.3 Payload Format Indicator 【1字节】
//3.1.3.2.4 Message Expiry Interval 【4字节】
//3.1.3.2.5 Content Type【UTF-8 String】
//3.1.3.2.6 Response Topic【UTF-8 String】
//3.1.3.2.7 Correlation Data 【Binary Data】
//3.1.3.2.8 User Property【UTF-8 String Pair】
//3.1.3.3 Will Topic 【UTF-8 String】
//3.1.3.4 Will Payload【 Binary Data】
//3.1.3.5 User Name【UTF-8 String】
//3.1.3.6 Password【 Binary Data】
//3.1.4 CONNECT Actions


public static getFixHeader(): Uint8Array{
let remainLength: number = 0


  <span class="hljs-comment"><span class="hljs-comment">//3.1.1 CONNECT Fixed Header - 包类型</span></span>
   <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> abPacketType = <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> <span class="hljs-built_in"><span class="hljs-built_in">ArrayBuffer</span></span>(<span class="hljs-number"><span class="hljs-number">1</span></span>)
   <span class="hljs-keyword"><span class="hljs-keyword">const</span></span> dv_abPacketType = <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> <span class="hljs-built_in"><span class="hljs-built_in">DataView</span></span>(abPacketType);
   dv_abPacketType.setInt8(<span class="hljs-number"><span class="hljs-number">0</span></span>, <span class="hljs-number"><span class="hljs-number">0x10</span></span>)

  <span class="hljs-comment"><span class="hljs-comment">//3.1.2.1 Protocol Name</span></span>

  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> u8a_protolName = <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.utf8String(<span class="hljs-string"><span class="hljs-string">'MQTT'</span></span>)
  remainLength += u8a_protolName.length

  <span class="hljs-comment"><span class="hljs-comment">//3.1.2.2 Protocol Version</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> version = <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> <span class="hljs-built_in"><span class="hljs-built_in">Uint8Array</span></span>([<span class="hljs-number"><span class="hljs-number">5</span></span>])
  remainLength++

  <span class="hljs-comment"><span class="hljs-comment">//3.1.2.3 Connect Flags</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">const</span></span>  UserNameFlag: number = <span class="hljs-number"><span class="hljs-number">0x80</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">const</span></span>  PasswordFlag: number = <span class="hljs-number"><span class="hljs-number">0x40</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">const</span></span>  WillRetain: number = <span class="hljs-number"><span class="hljs-number">0x20</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">const</span></span>  WillQoS0: number = <span class="hljs-number"><span class="hljs-number">0x00</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">const</span></span>  WillQoS1: number = <span class="hljs-number"><span class="hljs-number">0x8</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">const</span></span>  WillQoS2: number = <span class="hljs-number"><span class="hljs-number">0x10</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">const</span></span>  WillQoS3: number = <span class="hljs-number"><span class="hljs-number">0x18</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">const</span></span>  WillFlag: number = <span class="hljs-number"><span class="hljs-number">0x4</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">const</span></span>  CleanStart: number = <span class="hljs-number"><span class="hljs-number">0x2</span></span>

  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> connectFlags: number = <span class="hljs-number"><span class="hljs-number">0</span></span>
  <span class="hljs-comment"><span class="hljs-comment">//可以根据实际对外暴露的接口,在这里进行与运算</span></span>
  connectFlags = CleanStart
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> u8a_connectFlags = <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> <span class="hljs-built_in"><span class="hljs-built_in">Uint8Array</span></span>([connectFlags])
  remainLength++

  <span class="hljs-comment"><span class="hljs-comment">//3.1.2.10 Keep Alive</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">const</span></span> keepAlive = <span class="hljs-number"><span class="hljs-number">60</span></span>

  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> u8a_keepalive = <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> <span class="hljs-built_in"><span class="hljs-built_in">Uint8Array</span></span>([(keepAlive &amp; <span class="hljs-number"><span class="hljs-number">0xff00</span></span>) &gt;&gt; <span class="hljs-number"><span class="hljs-number">8</span></span> , keepAlive &amp; <span class="hljs-number"><span class="hljs-number">0xff</span></span>])
  remainLength += <span class="hljs-number"><span class="hljs-number">2</span></span>

  <span class="hljs-comment"><span class="hljs-comment">//3.1.2.11 CONNECT Properties</span></span>
  <span class="hljs-comment"><span class="hljs-comment">//3.1.2.11.1 Property Length</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> u8a_propertylength = <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> <span class="hljs-built_in"><span class="hljs-built_in">Uint8Array</span></span>([<span class="hljs-number"><span class="hljs-number">0</span></span>])
  remainLength++

  <span class="hljs-comment"><span class="hljs-comment">//3.1.3 CONNECT Payload</span></span>
  <span class="hljs-comment"><span class="hljs-comment">//3.1.3.1 Client Identifier (ClientID)</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> u8a_clientidentifier = <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.utf8String(<span class="hljs-string"><span class="hljs-string">'Harvey鸿蒙'</span></span>)
  remainLength += u8a_clientidentifier.length

  <span class="hljs-comment"><span class="hljs-comment">//3.1.1 CONNECT Fixed Header - 包剩余长度</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> abRemainLength = <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> <span class="hljs-built_in"><span class="hljs-built_in">ArrayBuffer</span></span>(<span class="hljs-number"><span class="hljs-number">1</span></span>)
  <span class="hljs-keyword"><span class="hljs-keyword">const</span></span> dv_remainLength = <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> <span class="hljs-built_in"><span class="hljs-built_in">DataView</span></span>(abRemainLength);
  dv_remainLength.setInt8(<span class="hljs-number"><span class="hljs-number">0</span></span>, remainLength)

  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> allIndex: number = <span class="hljs-number"><span class="hljs-number">0</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> allUint8Array = <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> <span class="hljs-built_in"><span class="hljs-built_in">Uint8Array</span></span>(<span class="hljs-number"><span class="hljs-number">2</span></span> + remainLength)
  allUint8Array[allIndex++] = dv_abPacketType.getUint8(<span class="hljs-number"><span class="hljs-number">0</span></span>) <span class="hljs-comment"><span class="hljs-comment">//包类型</span></span>
  allUint8Array[allIndex++] = dv_remainLength.getUint8(<span class="hljs-number"><span class="hljs-number">0</span></span>) <span class="hljs-comment"><span class="hljs-comment">//包剩余长度</span></span>
  u8a_protolName.forEach((value)=&gt;{                       <span class="hljs-comment"><span class="hljs-comment">//协议名称</span></span>
     allUint8Array[allIndex++] = value
  })
  version.forEach((value)=&gt;{                              <span class="hljs-comment"><span class="hljs-comment">//协议版本号</span></span>
     allUint8Array[allIndex++] = value
  })
  u8a_connectFlags.forEach((value)=&gt;{                     <span class="hljs-comment"><span class="hljs-comment">//连接标志</span></span>
     allUint8Array[allIndex++] = value
  })
  u8a_keepalive.forEach((value)=&gt;{                        <span class="hljs-comment"><span class="hljs-comment">//长连保活时间</span></span>
     allUint8Array[allIndex++] = value
  })
  u8a_propertylength.forEach((value)=&gt;{                   <span class="hljs-comment"><span class="hljs-comment">//连接属性长度</span></span>
     allUint8Array[allIndex++] = value
  })
  u8a_clientidentifier.forEach((value)=&gt;{                 <span class="hljs-comment"><span class="hljs-comment">//客户端名称</span></span>
     allUint8Array[allIndex++] = value
  })

  <span class="hljs-comment"><span class="hljs-comment">//数值打印</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> str = [...new <span class="hljs-built_in"><span class="hljs-built_in">Uint8Array</span></span>(abPacketType),...new <span class="hljs-built_in"><span class="hljs-built_in">Uint8Array</span></span>(abRemainLength), ...u8a_protolName, ...version
      , ...u8a_connectFlags, ...u8a_keepalive, ...u8a_propertylength, ...u8a_clientidentifier]
     .map(x =&gt; x.toString(<span class="hljs-number"><span class="hljs-number">16</span></span>).padStart(<span class="hljs-number"><span class="hljs-number">2</span></span>, <span class="hljs-string"><span class="hljs-string">'0'</span></span>))
     .join(<span class="hljs-string"><span class="hljs-string">' '</span></span>)

  console.log(str)

  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> allStr: string = <span class="hljs-string"><span class="hljs-string">''</span></span>

  allUint8Array.forEach((value) =&gt; {
     allStr = allStr.concat(value.toString(<span class="hljs-number"><span class="hljs-number">16</span></span>).padStart(<span class="hljs-number"><span class="hljs-number">2</span></span>, <span class="hljs-string"><span class="hljs-string">'0'</span></span>)).concat(<span class="hljs-string"><span class="hljs-string">' '</span></span>)
  })
  console.log(allStr)

  <span class="hljs-keyword"><span class="hljs-keyword">return</span></span> allUint8Array
}


private static utf8String(content: string): Uint8Array{
const encoder = new util.TextEncoder()
let u8a_encoder = encoder.encodeInto(content)


  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> encoderLength = u8a_encoder.length

  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> abEncoder = <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> <span class="hljs-built_in"><span class="hljs-built_in">ArrayBuffer</span></span>(encoderLength + <span class="hljs-number"><span class="hljs-number">2</span></span>)
  <span class="hljs-keyword"><span class="hljs-keyword">const</span></span> dv_encoder = <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> <span class="hljs-built_in"><span class="hljs-built_in">DataView</span></span>(abEncoder)
  dv_encoder.setInt8(<span class="hljs-number"><span class="hljs-number">0</span></span>, (encoderLength &amp; <span class="hljs-number"><span class="hljs-number">0xff00</span></span>) &gt;&gt; <span class="hljs-number"><span class="hljs-number">8</span></span>)
  dv_encoder.setInt8(<span class="hljs-number"><span class="hljs-number">1</span></span>, encoderLength &amp; <span class="hljs-number"><span class="hljs-number">0x00ff</span></span>)

  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> index: number = <span class="hljs-number"><span class="hljs-number">2</span></span>
  u8a_encoder.forEach( (value) =&gt; {
     dv_encoder.setInt8(index++, value)
  })

  <span class="hljs-keyword"><span class="hljs-keyword">return</span></span> <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> <span class="hljs-built_in"><span class="hljs-built_in">Uint8Array</span></span>(abEncoder)
}


}

解析MQTT请求连接ACK数据

DevEco IDE 日志控制台

tcpSocket.on(‘message’ , ( value: {message: ArrayBuffer, remoteInfo: socket.SocketRemoteInfo} ) => {

let str = […new Uint8Array(value.message)] .map(x => x.toString(16).padStart(2, ‘0’)) .join(’ ')

console.log(str)

let index: number = 0

let uint8Array = new Uint8Array(value.message)

let cfh = uint8Array[index]

index++

//3.2.1 CONNACK Fixed Header //解析MQTT ACK数据,转换为日志输出 if(cfh == 32){ console.log(‘Fixed Header format:CONNACK(’+cfh+’)’) MQTTConnectACK.parse(index, uint8Array) }

getContext().eventHub.emit(‘remotemsg’, str) }) <button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

     

    

import MQTTTool from ‘./MQTTTool’

export default class MQTTConnectACK{

public static parse(index: number, uint8Array: Uint8Array) { let remainLength = uint8Array[index] console.log(‘Remaining Length:’ + remainLength.toString(16)) index++

  <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainLength == <span class="hljs-number"><span class="hljs-number">0</span></span>){
    <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
  }

  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> remainIndex: number = <span class="hljs-number"><span class="hljs-number">0</span></span>

  <span class="hljs-comment"><span class="hljs-comment">//3.2.2 CONNACK Variable Header</span></span>
  <span class="hljs-comment"><span class="hljs-comment">//3.2.2.1 Connect Acknowledge Flags</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> caf = uint8Array[index]
  console.log(<span class="hljs-string"><span class="hljs-string">'Connect Acknowledge Flags:'</span></span> + caf.toString(<span class="hljs-number"><span class="hljs-number">16</span></span>))
  index++
  remainIndex++

  <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainIndex &gt;= remainLength){
    <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
  }

  <span class="hljs-comment"><span class="hljs-comment">//3.2.2.2 Connect Reason Code</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> crc = uint8Array[index]
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> des: string = <span class="hljs-string"><span class="hljs-string">''</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">0</span></span>){
     des = <span class="hljs-string"><span class="hljs-string">'Success'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">128</span></span>){
     des = <span class="hljs-string"><span class="hljs-string">'Unspecified error'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">129</span></span>){
     des = <span class="hljs-string"><span class="hljs-string">'Malformed Packet'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">130</span></span>){
    des = <span class="hljs-string"><span class="hljs-string">'Protocol Error'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">131</span></span>){
    des = <span class="hljs-string"><span class="hljs-string">'Implementation specific error'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">132</span></span>){
    des = <span class="hljs-string"><span class="hljs-string">'Unsupported Protocol Version'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">133</span></span>){
    des = <span class="hljs-string"><span class="hljs-string">'Client Identifier not valid'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">134</span></span>){
    des = <span class="hljs-string"><span class="hljs-string">'Bad User Name or Password'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">135</span></span>){
    des = <span class="hljs-string"><span class="hljs-string">'Not authorized'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">136</span></span>){
    des = <span class="hljs-string"><span class="hljs-string">'Server unavailable'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">137</span></span>){
    des = <span class="hljs-string"><span class="hljs-string">'Server busy'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">138</span></span>){
    des = <span class="hljs-string"><span class="hljs-string">'Banned'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">140</span></span>){
    des = <span class="hljs-string"><span class="hljs-string">'Bad authentication method'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">144</span></span>){
    des = <span class="hljs-string"><span class="hljs-string">'Topic Name invalid'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">149</span></span>){
    des = <span class="hljs-string"><span class="hljs-string">'Packet too large'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">151</span></span>){
    des = <span class="hljs-string"><span class="hljs-string">'Quota exceeded'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">153</span></span>){
    des = <span class="hljs-string"><span class="hljs-string">'Payload format invalid'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">154</span></span>){
    des = <span class="hljs-string"><span class="hljs-string">'Retain not supported'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">155</span></span>){
    des = <span class="hljs-string"><span class="hljs-string">'QoS not supported'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">156</span></span>){
    des = <span class="hljs-string"><span class="hljs-string">'Use another server'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">157</span></span>){
    des = <span class="hljs-string"><span class="hljs-string">'Server moved'</span></span>
  } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(crc == <span class="hljs-number"><span class="hljs-number">158</span></span>){
    des = <span class="hljs-string"><span class="hljs-string">'Connection rate exceeded'</span></span>
  }
  console.log(<span class="hljs-string"><span class="hljs-string">'Connect Reason Code:'</span></span> + des)

  index++
  remainIndex++

  <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainIndex &gt;= remainLength){
    <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
  }

  <span class="hljs-comment"><span class="hljs-comment">//3.2.2.3 CONNACK Properties</span></span>
  <span class="hljs-comment"><span class="hljs-comment">//3.2.2.3.1 Property Length</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> propertyLength = uint8Array[index]
  console.log(<span class="hljs-string"><span class="hljs-string">'Property Length:'</span></span> + propertyLength.toString(<span class="hljs-number"><span class="hljs-number">16</span></span>))

  index++
  remainIndex++

  <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(propertyLength != <span class="hljs-number"><span class="hljs-number">0</span></span>){

    <span class="hljs-keyword"><span class="hljs-keyword">while</span></span> (<span class="hljs-literal"><span class="hljs-literal">true</span></span>){
      <span class="hljs-comment"><span class="hljs-comment">//判断类型</span></span>
      <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> nextType = uint8Array[index]

      index++
      remainIndex++
      <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainIndex &gt;= remainLength){
        <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
      }

      <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(nextType == <span class="hljs-number"><span class="hljs-number">17</span></span>){ <span class="hljs-comment"><span class="hljs-comment">//值为4个字节</span></span>
        <span class="hljs-comment"><span class="hljs-comment">//3.2.2.3.2 Session Expiry Interval</span></span>
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> costByteNumber = MQTTTool.parseFourByte(uint8Array, index, <span class="hljs-string"><span class="hljs-string">"Session Expiry Interval:"</span></span>)
        index += costByteNumber
        remainIndex += costByteNumber

        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainIndex &gt;= remainLength){
          <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
        }

      } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(nextType == <span class="hljs-number"><span class="hljs-number">33</span></span>){<span class="hljs-comment"><span class="hljs-comment">//值为2个字节</span></span>

        <span class="hljs-comment"><span class="hljs-comment">//3.2.2.3.3 Receive Maximum</span></span>
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> costByteNumber = MQTTTool.parseTwoByte(uint8Array, index, <span class="hljs-string"><span class="hljs-string">"Receive Maximum:"</span></span>)
        index += costByteNumber
        remainIndex += costByteNumber

        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainIndex &gt;= remainLength){
          <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
        }

      } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(nextType == <span class="hljs-number"><span class="hljs-number">36</span></span>){ <span class="hljs-comment"><span class="hljs-comment">//值为1个字节</span></span>

        <span class="hljs-comment"><span class="hljs-comment">//3.2.2.3.4 Maximum QoS</span></span>
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> mq = uint8Array[index]
        console.log(<span class="hljs-string"><span class="hljs-string">'Maximum QoS:'</span></span> + mq.toString(<span class="hljs-number"><span class="hljs-number">16</span></span>))

        index++
        remainIndex++

        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainIndex &gt;= remainLength){
          <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
        }

      } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(nextType == <span class="hljs-number"><span class="hljs-number">37</span></span>) {  <span class="hljs-comment"><span class="hljs-comment">//值为1个字节</span></span>
        <span class="hljs-comment"><span class="hljs-comment">//3.2.2.3.5 Retain Available</span></span>
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> ra = uint8Array[index]
        console.log(<span class="hljs-string"><span class="hljs-string">'Retain Available:'</span></span> + ra.toString(<span class="hljs-number"><span class="hljs-number">16</span></span>))

        index++
        remainIndex++

        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainIndex &gt;= remainLength){
          <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
        }
      } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(nextType == <span class="hljs-number"><span class="hljs-number">39</span></span>) { <span class="hljs-comment"><span class="hljs-comment">//值为4个字节</span></span>

        <span class="hljs-comment"><span class="hljs-comment">//3.2.2.3.6 Maximum Packet Size</span></span>
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> costByteNumber = MQTTTool.parseFourByte(uint8Array, index, <span class="hljs-string"><span class="hljs-string">"Maximum Packet Size:"</span></span>)
        index += costByteNumber
        remainIndex += costByteNumber

        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainIndex &gt;= remainLength){
          <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
        }

      } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(nextType == <span class="hljs-number"><span class="hljs-number">18</span></span>) { <span class="hljs-comment"><span class="hljs-comment">//UTF-8 String = 2个字节 + 2个字节值的字节</span></span>

        <span class="hljs-comment"><span class="hljs-comment">//3.2.2.3.7 Assigned Client Identifier</span></span>
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> costByteNumber = MQTTTool.parseUTF8String(uint8Array, index, <span class="hljs-string"><span class="hljs-string">"Assigned Client Identifier:"</span></span>)
        index += costByteNumber
        remainIndex += costByteNumber

        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainIndex &gt;= remainLength){
          <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
        }

      } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(nextType == <span class="hljs-number"><span class="hljs-number">34</span></span>) { <span class="hljs-comment"><span class="hljs-comment">// 值为2个字节</span></span>
        <span class="hljs-comment"><span class="hljs-comment">//3.2.2.3.8 Topic Alias Maximum</span></span>
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> costByteNumber = MQTTTool.parseTwoByte(uint8Array, index, <span class="hljs-string"><span class="hljs-string">"Topic Alias Maximum:"</span></span>)
        index += costByteNumber
        remainIndex += costByteNumber

        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainIndex &gt;= remainLength){
          <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
        }

      } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(nextType == <span class="hljs-number"><span class="hljs-number">31</span></span>) { <span class="hljs-comment"><span class="hljs-comment">//UTF-8 String = 2个字节 + 2个字节值的字节</span></span>
        <span class="hljs-comment"><span class="hljs-comment">//3.2.2.3.9 Reason String</span></span>
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> costByteNumber = MQTTTool.parseUTF8String(uint8Array, index, <span class="hljs-string"><span class="hljs-string">"Reason String:"</span></span>)
        index += costByteNumber
        remainIndex += costByteNumber

        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainIndex &gt;= remainLength){
          <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
        }

      } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(nextType == <span class="hljs-number"><span class="hljs-number">38</span></span>) {<span class="hljs-comment"><span class="hljs-comment">//UTF-8 String Pair = (2个字节 + 2个字节值的字节)+(2个字节 + 2个字节值的字节)</span></span>
        <span class="hljs-comment"><span class="hljs-comment">//3.2.2.3.10 User Property</span></span>
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> costByteNumber = MQTTTool.parseUTF8String(uint8Array, index, <span class="hljs-string"><span class="hljs-string">"User Property:"</span></span>)
        index += costByteNumber
        remainIndex += costByteNumber

        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainIndex &gt;= remainLength){
          <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
        }

      } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(nextType == <span class="hljs-number"><span class="hljs-number">40</span></span>) { <span class="hljs-comment"><span class="hljs-comment">//值为1个字节</span></span>
        <span class="hljs-comment"><span class="hljs-comment">//3.2.2.3.11 Wildcard Subscription Available</span></span>
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> wsa = uint8Array[index]
        console.log(<span class="hljs-string"><span class="hljs-string">'Wildcard Subscription Available:'</span></span> + wsa.toString(<span class="hljs-number"><span class="hljs-number">16</span></span>))

        index++
        remainIndex++

        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainIndex &gt;= remainLength){
          <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
        }
      } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(nextType == <span class="hljs-number"><span class="hljs-number">41</span></span>) { <span class="hljs-comment"><span class="hljs-comment">//值为1个字节</span></span>
        <span class="hljs-comment"><span class="hljs-comment">//3.2.2.3.12 Subscription Identifiers Available</span></span>
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> sia = uint8Array[index]
        console.log(<span class="hljs-string"><span class="hljs-string">'Subscription Identifiers Available:'</span></span> + sia.toString(<span class="hljs-number"><span class="hljs-number">16</span></span>))

        index++
        remainIndex++

        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainIndex &gt;= remainLength){
          <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
        }

      } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(nextType == <span class="hljs-number"><span class="hljs-number">42</span></span>) { <span class="hljs-comment"><span class="hljs-comment">//值为1个字节</span></span>
        <span class="hljs-comment"><span class="hljs-comment">//3.2.2.3.13 Shared Subscription Available</span></span>
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> ssa = uint8Array[index]
        console.log(<span class="hljs-string"><span class="hljs-string">'Shared Subscription Available:'</span></span> + ssa.toString(<span class="hljs-number"><span class="hljs-number">16</span></span>))

        index++
        remainIndex++

        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainIndex &gt;= remainLength){
          <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
        }
      } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(nextType == <span class="hljs-number"><span class="hljs-number">19</span></span>) { <span class="hljs-comment"><span class="hljs-comment">//值为2个字节</span></span>
        <span class="hljs-comment"><span class="hljs-comment">//3.2.2.3.14 Server Keep Alive</span></span>
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> costByteNumber = MQTTTool.parseTwoByte(uint8Array, index, <span class="hljs-string"><span class="hljs-string">"Server Keep Alive:"</span></span>)
        index += costByteNumber
        remainIndex += costByteNumber

        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainIndex &gt;= remainLength){
          <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
        }

      } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(nextType == <span class="hljs-number"><span class="hljs-number">26</span></span>) { <span class="hljs-comment"><span class="hljs-comment">//UTF-8 String = 2个字节 + 2个字节值的字节</span></span>
        <span class="hljs-comment"><span class="hljs-comment">//3.2.2.3.15 Response Information</span></span>
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> costByteNumber = MQTTTool.parseUTF8String(uint8Array, index, <span class="hljs-string"><span class="hljs-string">"Response Information:"</span></span>)
        index += costByteNumber
        remainIndex += costByteNumber

        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainIndex &gt;= remainLength){
          <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
        }

      } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(nextType == <span class="hljs-number"><span class="hljs-number">28</span></span>) { <span class="hljs-comment"><span class="hljs-comment">//UTF-8 String = 2个字节 + 2个字节值的字节</span></span>
        <span class="hljs-comment"><span class="hljs-comment">//3.2.2.3.16 Server Reference</span></span>
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> costByteNumber = MQTTTool.parseUTF8String(uint8Array, index, <span class="hljs-string"><span class="hljs-string">"Server Reference:"</span></span>)
        index += costByteNumber
        remainIndex += costByteNumber

        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainIndex &gt;= remainLength){
          <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
        }

      } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(nextType == <span class="hljs-number"><span class="hljs-number">21</span></span>) { <span class="hljs-comment"><span class="hljs-comment">//UTF-8 String = 2个字节 + 2个字节值的字节</span></span>
        <span class="hljs-comment"><span class="hljs-comment">//3.2.2.3.17 Authentication Method</span></span>
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> costByteNumber = MQTTTool.parseUTF8String(uint8Array, index, <span class="hljs-string"><span class="hljs-string">"Authentication Method:"</span></span>)
        index += costByteNumber
        remainIndex += costByteNumber

        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainIndex &gt;= remainLength){
          <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
        }

      } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(nextType == <span class="hljs-number"><span class="hljs-number">22</span></span>) { <span class="hljs-comment"><span class="hljs-comment">//Binary Data = 2个字节 + 2个字节值的字节</span></span>
        <span class="hljs-comment"><span class="hljs-comment">//3.2.2.3.18 Authentication Data</span></span>
        <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> costByteNumber = MQTTTool.parseBinaryData(uint8Array, index, <span class="hljs-string"><span class="hljs-string">"Authentication Data:"</span></span>)
        index += costByteNumber
        remainIndex += costByteNumber

        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(remainIndex &gt;= remainLength){
          <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>
        }

      }
    }

}

}

}

最终效果

总结

Socket 用起来不错

3 回复

大佬欢迎开源

bindAddress:
address: '192.168.71.66',
port: 1983,

这些数据是从哪获取到的。

在HarmonyOS上进行Socket小试并实现MQTT连接,您需要确保已正确配置网络权限,并使用了适当的MQTT库。以下是一些基本步骤和注意事项:

  1. 网络权限配置: 在config.json文件中添加必要的网络权限,例如ohos.permission.INTERNETohos.permission.ACCESS_NETWORK_STATE,以确保应用可以访问网络。

  2. MQTT库选择: HarmonyOS支持多种MQTT库,如Eclipse Paho等。您可以选择合适的库,并将其集成到您的项目中。

  3. Socket编程: 使用Java或C++进行Socket编程,建立TCP连接。这是MQTT连接的基础。

  4. MQTT客户端配置: 使用选定的MQTT库创建MQTT客户端,配置服务器地址、端口、客户端ID等参数。

  5. 连接与订阅: 调用MQTT客户端的connect方法建立连接,然后使用subscribe方法订阅主题。

  6. 消息处理: 实现回调方法以处理接收到的消息。

  7. 断开连接: 在不再需要时,调用disconnect方法断开MQTT连接。

确保您的HarmonyOS设备已连接到互联网,并且MQTT服务器可访问。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部