0


OpenHarmony(数据)通信协议、数据存储—protobuf

介绍

ProtoBuf(protocol buffers) 是一种语言无关、平台无关、可扩展的序列化结构数据的方法,它可用于(数据)通信协议、数据存储等。,是一种灵活,高效,自动化机制的结构数据序列化方法比XML更小,更快,更为简单。

本项目主要是OpenHarmony系统下以protobuf.js 5.0.3为主要依赖开发,主要接口针对OpenHarmony系统进行合理的适配研发。

下载安装

1.安装

ohpm install @ohos/protobufjs

2.在需要使用的页面导入protobuf

import protobuf from '@ohos/protobufjs'

使用说明

protobuf支持的输入格式

1.proto格式字符串

const protoStr = 'syntax = "proto3"; package com.user;message UserLoginResponse{string sessionId = 1;string userPrivilege = 2;bool isTokenType = 3;string formatTimestamp = 4;}';

2.proto文件映射的json字符串

const protoJson = '{
      "package": "com.user",
      "messages": [
        {
          "name": "UserLoginResponse",
          "fields": [
            {
              "rule": "optional",
              "type": "string",
              "name": "sessionId",
              "id": 1
            },
            {
              "rule": "optional",
              "type": "string",
              "name": "userPrivilege",
              "id": 2
            },
            {
              "rule": "optional",
              "type": "bool",
              "name": "isTokenType",
              "id": 3
            },
            {
              "rule": "optional",
              "type": "string",
              "name": "formatTimestamp",
              "id": 4
            }
          ]
        }
      ]
}'

3.proto文件

在resource->rawfile文件夹下按照 .proto文件格式定义消息体结构,如:userproto.proto文件。

syntax = "proto3";

package com.user;
message UserLoginResponse{
   string sessionId = 1;
   string userPrivilege = 2;
   bool isTokenType = 3;
   string formatTimestamp = 4;
}

4.json文件

在resource->rawfile文件夹下存放proto文件映射的json文件,参照第二点。

对象编解码

1.在resource->rawfile文件夹下按照 .proto文件格式定义消息体结构,如:userproto.proto文件。

syntax = "proto3";

package com.user;
message UserLoginResponse{
   string sessionId = 1;
   string userPrivilege = 2;
   bool isTokenType = 3;
   string formatTimestamp = 4;
}

2.读取.proto 文件

let builder = await Protobuf.loadProtoFile("userproto.proto", null, null, getContext(this).resourceManager)

3.对象编码

// 构建消息体
var UserLoginResponse = builder.build("com.user.UserLoginResponse");
let userLoginData = {
    sessionId: "testAsynchronouslyLoadProtoFile",
    userPrivilege: "John123",
    isTokenType: false,
    formatTimestamp: "12342222"
  };

// 对象编码的两种方式
// 方式一:通过消息体静态编码方法进行编码
var arrayBuffer = UserLoginResponse.encode(userLoginData).toArrayBuffer();

// 方式二:通过消息体实例进行编解码
var msg = new UserLoginResponse(userLoginData);
var arrayBuffer = msg.toArrayBuffer();

4.对象解码

let decode = UserLoginResponse.decode(arrayBuffer)

主要接口示例:

1.proto字符串编解码

Button("proto字符串编解码")
  .width('80%')
  .type(ButtonType.Capsule)
  .backgroundColor('#0D9FFB')
  .onClick(async () => {
    try {
      // 1.创建protbuf.Builder对象:用于构造协议消息体。
      var builder = protobuf.newBuilder();
      
      // 2.加载proto字符串:解析协议消息体定义。
      var root = await protobuf.loadProto(protoStr, builder, "user.proto");
      
      // 3.构建协议消息体。
      var UserLoginResponse = root.build("com.user.UserLoginResponse");
      
      // 设置编解码数据
      const userLogin = {
        sessionId: "loadProto",
        userPrivilege: "John123",
        isTokenType: false,
        formatTimestamp: "12342222"
      };
      
      // 4.实例Message消息体:通过builder找到协议名后会产生Message,创建符合协议结构的数据对象,作为参数实例协议消息体。
      var msg = new UserLoginResponse(userLogin);
      
      // 5.消息体编码:可用于通信传递或存储
      var arrayBuffer = msg.toArrayBuffer();
      
      // 6.消息体解码:得到原始消息体内容
      var decodeMsg = UserLoginResponse.decode(arrayBuffer);
    } catch (error) {
      console.info('protobuf single file catch error: ' + error)
    }
  });

2.json字符串编解码

Button("json字符串编解码")
  .width('80%')
  .type(ButtonType.Capsule)
  .backgroundColor('#0D9FFB')
  .onClick(async () => {
    try {
      // 1.创建protbuf.Builder对象:用于构造协议消息体。
      var builder = protobuf.newBuilder();
      
      // 2.加载json字符串:解析协议消息体定义。
      var root = await protobuf.loadProto(protoJson, builder, "user.json");
      
      // 3.构建协议消息体。
      var UserLoginResponse = root.build("com.user.UserLoginResponse");
      
      // 设置编解码数据
      const userLogin = {
        sessionId: "loadJson",
        userPrivilege: "John123",
        isTokenType: false,
        formatTimestamp: "12342222"
      };
      
      // 4.实例Message消息体:通过builder找到协议名后会产生Message,创建符合协议结构的数据对象,作为参数实例协议消息体。
      var msg = new UserLoginResponse(userLogin);
      
      // 5.消息体编码:可用于通信传递或存储
      var arrayBuffer = msg.toArrayBuffer();
      
      // 6.消息体解码:得到原始消息体内容
      var decodeMsg = UserLoginResponse.decode(arrayBuffer);
    } catch (error) {
      console.info('protobuf single file catch error: ' + error)
    }
  });

3.同步方式进行proto文件编解码

Button("同步方式进行proto文件编解码")
  .width('80%')
  .type(ButtonType.Capsule)
  .backgroundColor('#0D9FFB')
  .onClick(async () => {
    try {
        // 读取文件需要借助全球化资源子系统中的ResourceManager来进行,支持多种方式获取
        // 方式一: 通过GlobalContext对象保存ability上下文中的resourceManager对象
        // 方式二: 通过getContext()方式获取
        // 在pages页面中获取: getContext(this).resourceManager
        let context: Context = GlobalContext.getContext().getObject("context") as Context;
        var builder = await protobuf.loadProtoFile('userproto.proto', null, null, context.resourceManager);
        if (!builder) {
          console.error('protobuf codec: builder is null|undefined.');
          return;
        }
        var UserLoginResponse = builder.build("com.user.UserLoginResponse");
        var msg = new UserLoginResponse(this.userLogin);
        var arrayBuffer = msg.toArrayBuffer();
        console.log("protobuf arrayBuffer:" + new Uint8Array(arrayBuffer));

        var decodeMsg = UserLoginResponse.decode(arrayBuffer);
        console.log("protobuf decode:" + JSON.stringify(decodeMsg));
      } catch (error) {
        console.info('protobuf single file catch error: ' + error)
      }
  });

4.异步方式进行proto文件编解码

Button("异步方式进行proto文件编解码")
  .width('80%')
  .type(ButtonType.Capsule)
  .backgroundColor('#0D9FFB')
  .onClick(() => {
    try {
      let context: Context = GlobalContext.getContext().getObject("context") as Context;
      protobuf.loadProtoFile('userproto.proto', (error, builder) => {
        if (error) {
          console.error('protobuf codec catch error: ' + error);
          return;
        }
        if (!builder) {
          console.error('protobuf codec: builder is null|undefined.');
          return;
        }
        var UserLoginResponse = builder.build("com.user.UserLoginResponse");
        var msg = new UserLoginResponse(this.userLogin);
        console.log("protobuf msg:" 
        var arrayBuffer = msg.toArrayBuffer();
        console.log("protobuf arrayBuffer:" + new Uint8Array(arrayBuffer));
        this.bufferData = Array.prototype.toString.call(new Uint8Array(arrayBu
        var decodeMsg = UserLoginResponse.decode(arrayBuffer);
        console.log("protobuf decode:" + JSON.stringify(decodeMsg));
        this.decodeData = JSON.stringify(decodeMsg);
      }, null, context.resourceManager);
    } catch (error) {
      console.info('protobuf single file catch error: ' + error)
    }
  });

接口说明

loadProto

static loadProto(proto:string,builder?:ProtoBuf.Builder|string|{root: string, file: string},filename?:string|{root: string, file: string}) :ProtoBuf.Builder;

加载proto格式字符串,进行内容解析,并返回协议消息体构建器。

参数:
参数名类型必填说明protostring是proto格式的字符串。builderBuilder |string | {root: string, file: string}否指定已有的协议消息体构建器,如果未指定将重新创建一个。filenamestring | {root: string, file: string}否如果知道对应的文件名称,必须为导入文件指定。
返回值:
类型说明Builder协议消息体构建器。
protoFromString

static protoFromString(proto:string,builder?:ProtoBuf.Builder|string|{root: string, file: string},filename?:string|{root: string, file: string}) :ProtoBuf.Builder;

loadProto方法的别名,加载proto格式字符串,进行内容解析,并返回协议消息体构建器。

参数
参数名类型必填说明protostring是proto格式的字符串。builderBuilder |string | {root: string, file: string}否指定已有的协议消息体构建器,如果未指定将重新创建一个。filenamestring | {root: string, file: string}否如果知道对应的文件名称,必须为导入文件指定。
返回值:
类型说明Builder协议消息体构建器。
loadProtoFile

static loadProtoFile(filename:string|{root: string, file: string}, callback?=(error?:Error,builder:Protobuf.Builder)=>void,builder?:Protobuf.Builder,resourceManager: @ohos.resourceManager.ResourceManager):ProtoBuf.Builder|undefined;

加载proto文件,进行内容解析,并返回协议消息体构建器。
参数名类型必填说明filenamestring | {root: string, file: string}是原始文件的路径或指定’file’的对象,并为所有导入的文件覆盖’根’路径。callbackfunction否成功时将接收’ null '作为第一个参数,并将Builder作为第二个参数,否则将Error作为第一个参数。如果省略,文件将被同步读取。builderBuilder否指定已有的协议消息体构建器,如果未指定将重新创建一个。resourceManager@ohos.resourceManager.ResourceManager是访问应用资源的能力。
表1 callback的参数说明
参数名类型说明errorError如果解析成功,此参数返回’null’,如果失败,返回对应Error。builderBuilder协议消息体构建器。
返回值:
类型说明Builder | null协议消息体构建器。
protoFromFile

static protoFromFile(filename:string|{root: string, file: string}, callback?=(error?:Error,builder:Protobuf.Builder)=>void,builder?:Protobuf.Builder,resourceManager: @ohos.resourceManager.ResourceManager):ProtoBuf.Builder|undefined;

loadProtoFile方法别名,加载proto文件,进行内容解析,并返回协议消息体构建器。
参数名类型必填说明filenamestring | {root: string, file: string}是原始文件的路径或指定’file’的对象,并为所有导入的文件覆盖’根’路径。callbackfunction否成功时将接收’ null '作为第一个参数,并将Builder作为第二个参数,否则将Error作为第一个参数。如果省略,文件将被同步读取。builderBuilder否指定已有的协议消息体构建器,如果未指定将重新创建一个。resourceManager@ohos.resourceManager.ResourceManager是访问应用资源的能力。
表1 callback的参数说明
参数名类型说明errorError如果解析成功,此参数返回’null’,如果失败,返回对应Error。builderBuilder协议消息体构建器。
返回值:
类型说明Builder | undefined协议消息体构建器。
loadJson

static loadJson(json:string|any, builder?:Protobuf.Builder|string| {root: string, file: string}, filename?: string| {root: string, file: string} ): ProtoBuf.Builder;

参数:
参数名类型必填说明jsonstring | any是proto格式的json字符串或者proto文件对应的json对象。builderBuilder |string | {root: string, file: string}否指定已有的协议消息体构建器,如果未指定将重新创建一个。filenamestring | {root: string, file: string}否如果知道对应的文件名称,必须为导入文件指定。
返回值:
类型说明Builder协议消息体构建器。
loadJsonFile

static loadJsonFile(filename:string|{root: string, file: string}, callback?=(error?:Error,builder:Protobuf.Builder)=>void,builder?:Protobuf.Builder,resourceManager: @ohos.resourceManager.ResourceManager):ProtoBuf.Builder|undefined;

加载proto文件,进行内容解析,并返回协议消息体构建器。
参数名类型必填说明filenamestring | {root: string, file: string}是原始文件的路径或指定’file’的对象,并为所有导入的文件覆盖’根’路径。callbackfunction否成功时将接收’ null '作为第一个参数,并将Builder作为第二个参数,否则将Error作为第一个参数。如果省略,文件将被同步读取。builderBuilder否指定已有的协议消息体构建器,如果未指定将重新创建一个。resourceManager@ohos.resourceManager.ResourceManager是访问应用资源的能力。
表1 callback的参数说明
参数名类型说明errorError如果解析成功,此参数返回’null’,如果失败,返回对应Error。builderBuilder协议消息体构建器。
返回值:
类型说明Builder | undefined协议消息体构建器。
newBuilder

static newBuilder():Protobuf.Builder;

返回值:
类型说明Builder协议消息体构建器。
Util

以下接口在Util对象内,须通过Protobuf.Util方式调用。

fetch

static fetch(path:string, callback?:(content?:string)=> void):string|undefined.

获取文件内容,需要先设置资源文件读取对象ResourceManager。

参数:
参数名类型必填说明pathstring是资源文件路径。callback(content?:string)=> void否回调接收资源的内容。如果省略,资源将被同步获取。如果请求失败,内容将为空。
返回值:
类型说明string | undefined资源文件内容。
toCamelCase

static toCamelCase(str:string):string;

用于将字符串转换为驼峰格式。

参数:
参数名类型必填说明strstring是将字符串转换为驼峰格式。
返回值:
类型说明string驼峰格式字符串。
Builder

构建协议消息体的构建器,提供构建协议消息的功能。

isMessage

static isMessage(def:Object):boolean;

用于判断指定对象是否为消息体。

参数:
参数名类型必填说明defObject是判断指定对象是否为消息体。
返回值:
类型说明boolean指示对象是否为消息体。
isMessageField

static isMessageField(def:Object):boolean;

用于判断指定对象是否为消息体的字段。

参数:
参数名类型必填说明defObject是判断指定对象是否为消息体的字段。
返回值:
类型说明boolean指示对象是否为消息体的字段。
isEnum

static isEnum(def:Object):boolean;

用于判断指定对象是否为枚举对象。

参数:
参数名类型必填说明defObject是判断指定对象是否为枚举对象。
返回值:
类型说明boolean指示对象是否为枚举对象。
build

build(path?: string | string[]) : Protobuf.Builder.Message | Object;

用于构建协议,解析所有定义,返回构建的协议消息包。

参数:
参数名类型必填说明pathstring | string[]否协议内包完整路径。
返回值:
类型说明Protobuf.Builder.Message | Object协议消息包。
lookup

lookup(path?: string, excludeNonNamespace?: boolean) : ProtoBuf.Reflect.T;

用于构建协议消息包。

参数:
参数名类型必填说明pathstring否协议内包完整路径。excludeNonNamespaceboolean否排除非命名空间类型,如fields,默认为false。
返回值:
类型说明ProtoBuf.Reflect.T反射的描述。
Message

提供协议消息体的编解码方法。

constructor

new Message(values:Object);

构建消息体实例。
参数名类型必填说明valuesObject是符合协议消息体结构的数据对象。
encode

static encode(data: Object, buffer?: ByteBuffer | boolean, noVerify?: boolean):ByteBuffer;

将协议消息体编码为ByteBuffer格式。

参数:
参数名类型必填说明datastring是消息体对应的数据。bufferboolean否指定编解码结果的ByteBuffer对象,如果未指定,将创建一个新的。noVerifyboolean否是否不验证字段值,默认为false。
返回值:
类型说明ByteBuffer协议消息体数据编码后的ByteBuffer数据。
encode

encode(buffer?: ByteBuffer| boolean, noVerify?: boolean): ByteBuffer;

将消息编码为ByteBuffer格式数据。

参数:
参数名类型必填说明bufferstring是指定编解码结果的ByteBuffer对象,如果未指定,将创建一个新的。noVerifyboolean否是否不验证字段值,默认为false。
返回值:
类型说明ByteBuffer协议消息体数据编码后的ByteBuffer数据。
encodeAB

encodeAB():ArrayBuffer;

将消息编码为ArrayBuffer格式。

返回值:
类型说明ArrayBuffer协议消息体数据编码后的ArrayBuffer数据。
toArrayBuffer

toArrayBuffer():ArrayBuffer;

encodeAB方法的别名,用于将消息编码为ArrayBuffer格式。

返回值:
类型说明ArrayBuffer协议消息体数据编码后的ArrayBuffer数据。
calculate

calculate(): Number;

计算消息体长度。

返回值:
类型说明Number协议消息体的长度。
encodeDelimited

encodeDelimited(buffer?: ByteBuffer| boolean, noVerify?: boolean): ByteBuffer;

将消息编码为ByteBuffer格式数据。

参数:
参数名类型必填说明bufferstring是指定编解码结果的ByteBuffer对象,如果未指定,将创建一个新的。noVerifyboolean否是否不验证字段值,默认为false。
返回值:
类型说明ByteBuffer协议消息体数据编码后的ByteBuffer数据。
encode64

encode64(): string;

将消息编码为base64编码的字符串。

返回值:
类型说明string将消息编码为base64编码的字符串。
toBase64

toBase64(): string;

encode64方法的别名,将消息编码为base64编码的字符串。

返回值:
类型说明string将消息编码为base64编码的字符串。
encodeHex

encodeHex(): string;

将消息编码为十六进制编码的字符串。

返回值:
类型说明string将消息编码为十六进制编码的字符串。
toHex

toHex(): string;

encodeHex方法的别名,将消息编码为十六进制编码的字符串。

返回值:
类型说明string将消息编码为十六机制编码的字符串。
encodeJson

encodeJson(): string;

将消息编码为Json字符串。

返回值:
类型说明string将消息编码为Json字符串。
toRaw

toRaw(binaryAsBase64?:boolean, longsAsStrings:boolean):Object;

返回消息的原始负载。

参数:
参数名类型必填说明databinaryAsBase64boolean否指示是否包含二进制数据作为base64字符串而不是缓冲区,默认为false。longsAsStringsboolean是指示是否将long编码为字符串。
返回值:
类型说明Object返回消息的原始负载。
decode

static decode(data: ByteBuffer|ArrayBuffer|Buffer|string, length?: Number| string, enc?: string):Protobuf.Builder.Message;

从指定的缓冲区或字符串解码消息。

参数:
参数名类型必填说明dataByteBuffer | ArrayBuffer | Buffer | string是要解码的数据。lengthNumber | string否消息体长度,默认解码所有数据。encstring否如果缓冲区是字符串,将进行编码,支持hex,base64,utf8(不推荐),默认为base64
返回值:
类型说明Protobuf.Builder.Message从指定的缓冲区或字符串解码消息。
decode64

static decode64(str:string):Protobuf.Builder.Message;

从指定的base64编码字符串解码消息。

参数:
参数名类型必填说明strstring是要解码的base64编码字符串数据。
返回值:
类型说明Protobuf.Builder.Message从指定的base64编码字符串解码消息。
decodeHex

static decodeHex(str:string):Protobuf.Builder.Message;

从指定的十六进制编码字符串解码消息。

参数:
参数名类型必填说明strstring是要解码的十六进制编码字符串数据。
返回值:
类型说明Protobuf.Builder.Message从指定的十六进制编码字符串解码消息。
decodeJson

static decodeJson(str:string):Protobuf.Builder.Message;

从JSON字符串解码消息。

参数:
参数名类型必填说明strstring是从JSON字符串解码消息。
返回值:
类型说明Protobuf.Builder.Message从JSON字符串解码消息。
decodeDelimited

static decodeDelimited(buffer: ByteBuffer | ArrayBuffer | Buffer | string, enc?: string):Protobuf.Builder.Message;

从指定的缓冲区或字符串解码以长度分隔的varint32消息。

参数:
参数名类型必填说明bufferByteBuffer | ArrayBuffer | Buffer | string是指定的缓冲区或字符串。encstring否如果缓冲区是字符串,将进行编码,支持hex,base64,utf8(不推荐),默认为base64。
返回值:
类型说明Protobuf.Builder.Message从指定的缓冲区或字符串解码以长度分隔的varint32消息。

约束与限制

在下述版本验证通过:

  • DevEco Studio: 4.0 (4.0.3.512), SDK: API10 (4.0.10.9)
  • DevEco Studio: 4.0 Release(4.0.3.413), SDK: API10 (4.0.10.3)

目录结构

|---- protobuf
|     |---- AppScrope  # 示例代码文件夹
|     |---- entry  # 示例代码文件夹
|     |---- protobufjs  # protobufjs库文件夹
|           |---- src/main  # 模块代码
|                |---- ets/   # 模块代码
|                     |---- dist     # 打包文件
|            |---- index.ets          # 入口文件
|            |---- .ohpmignore        # ohpm发布的忽略文件
|            |---- *.json5      # 配置文件
|     |---- README.md  # 安装使用方法
|     |---- README.OpenSource  # 开源说明
|     |---- CHANGELOG.md  # 更新日志

经常有很多小伙伴抱怨说:不知道学习鸿蒙开发哪些技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?

为了能够帮助到大家能够有规划的学习,这里特别整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、WebGL、元服务、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植等等)鸿蒙(HarmonyOS NEXT)技术知识点。

在这里插入图片描述

《鸿蒙 (Harmony OS)开发学习手册》(共计892页)

如何快速入门?

1.基本概念
2.构建第一个ArkTS应用
3.……

开发基础知识:gitee.com/MNxiaona/733GH

1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……

基于ArkTS 开发

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

鸿蒙开发面试真题(含参考答案):gitee.com/MNxiaona/733GH

OpenHarmony 开发环境搭建
图片

《OpenHarmony源码解析》

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ……
  • 系统架构分析
  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ……

图片

OpenHarmony 设备开发学习手册

图片

写在最后

  • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请移步前往小编:gitee.com/MNxiaona/733GH


本文转载自: https://blog.csdn.net/u012165769/article/details/141168124
版权归原作者 OH五星上将 所有, 如有侵权,请联系我们删除。

“OpenHarmony(数据)通信协议、数据存储—protobuf”的评论:

还没有评论