欢迎访问Ningto's博客

Menu
  • 首页
  • 归档
  • 关于
  • 书签
  • 必应壁纸
  • IT聚合
  • 工具
    • 我的工具列表
    • 我的网盘
    • 必应每日壁纸API
    • Html转Markdown
    • 仙尘光标
Menu

react native中使用protobufjs

最后更新 2018-02-25 13:55:21   阅读量 4837

Table of Contents

  • 1. 载入proto文件
  • 2. lookuptypeorenum
  • 3. 代码片段

javascript使用protobuf google官方已经支持了可以看这里,我只是简单的试用了下没有深究,这篇文章介绍的是dcodeIOde的protobuf.js库,web端使用还是蛮方便的,但在react native中遇到了一些坑。

载入proto文件

使用如下代码载入proto文件是不行的

var protobuf = require("protobufjs");
protobuf.load(protoFilePath)

可以用这个库自身提供的工具将proto文件转换为json文件,如:

pbjs -t json file1.proto file2.proto > bundle.json

然后,使用json的相对路径就可以load成功了

lookupTypeOrEnum

载入proto文件成功后会返回一个root对象(代表了整个proto中的package),使用root.lookupTypeOrEnum查找package中的message,如果proto中有enum枚举类型会失败,翻看了一些Issues才找到解决办法,作者的回复如下:

I see. There have been similar issues in the past and iirc these are caused by recursive dependencies in the sources (enum.js requires something that again requires enum.js) that only react native isn't able to solve for some reason. This can be solved, usually, but requires checking all the dependencies and some reordering. Have you tried using the dist files instead?

讨论的地址:https://github.com/dcodeIO/protobuf.js/issues/964

我试过使用dist遇到了一些问题没有成功,根据其中一位用户的回复,在mac上将protobuf.js降级到6.8.0版本是可以的,后来我在windows上又不能使用了,折腾一番将其降级是6.7.0又可以了。

代码片段

/**
     * 构建一个protobuf包
     */
    buildProtoPackage: function(proto_package) {
      return new Promise((resolve, reject) => {
        // 缓存load后的proto对象
        if (protobufBuilders[proto_package]) {
          return resolve(protobufBuilders[proto_package])
        }

        if (PROTO_FILE_DIR[PROTO_FILE_DIR.length - 1] !== '/') {
          PROTO_FILE_DIR += '/'
        }
        const protoFilePath = PROTO_FILE_DIR + proto_package + ".proto"
        ProtoBuf.load(protoFilePath).then((root) => {
          protobufBuilders[proto_package] = root;
          return resolve(root)
        }).catch((err) => {
          console.error('buildProtoPackage ', proto_package, err, protoFilePath)
          return reject(err)
        });
      })
    },
    /**
     * 构建一个protobuf对象
     */
    buildProtoObject: function(proto_package, proto_objectname) {
      return new Promise((resolve, reject) => {
        const packageName = proto_package
        const objectName = proto_objectname
        return this.buildProtoPackage(packageName).then((root) => {
          const obj = root.lookupTypeOrEnum(objectName)
          if (obj) {
            // console.log('buildProtoObject', proto_package, proto_objectname)
            return resolve(obj)
          }
          const errStr = 'builerProtoObject ' + objectName + ' failed'
          console.error(errStr)
          return reject(errStr)
        })
      })
    },
    request: function(cmd, proto_package, proto_request, proto_response, callback) {
      return this.buildProtoObject(proto_package, proto_request).then((obj) => {
        var payload = {}
        // 在上层填充数据
        callback.fillRequest(payload);
        // 验证填充的数据是否有效
        var errMsg = obj.verify(payload);
        if (errMsg) {
          console.error('requestOnce verify err', errMsg)
          throw Error(errMsg);
        }
        // 创建消息对象
        var message = obj.create(payload); // or use .fromObject if conversion is necessary
        // 编码二进制流
        var buffer = obj.encode(message).finish();
        // 包装成ByteBuffer
        buffer = ByteBuffer.wrap(buffer, "binary");
        this.sendmsg(cmd, buffer, proto_package, proto_response, callback, false);
      })
    },
(转载本站文章请注明作者和出处:泞途 - ningto.com)

下一篇 – nginx url跳转保留路径
上一篇 – One of the sources for assign has an enumerable key on the prototype chain

  1. React
  2. Javascript

toningto@outlook.com

推荐文章

Effective Python

Python的几种函数参数类型

标签云

MongoDB Mobile Boost Javascript Android Bug Mac Qt Windows Go Shell IOS Others Java Tools Design Tips Product Database Node.js Linux Python C/C++ Web MQ Life React

推广链接

【腾讯云】云产品限时秒杀,爆款1核2G云服务器,首年99元

多谢支持,用了好几年,服务很稳定支持多设备!

其他

文章RSS

Copyright © 2016 Welcome To Ningto Blog | 鄂ICP备17003086号-2