Giter Club home page Giter Club logo

protobufferforwechat's Introduction

微信小程序可用的Protobuf(含demo)

Protobuf: 一种轻便高效的结构化数据存储格式,平台无关、语言无关、可扩展,可用于通讯协议和数据存储等领域;

微信小程序: 基于微信平台的小程序

此库意义: 在微信小程序中Function 和 eval 相关的动态执行代码方式都给屏蔽了,以致google官方Protobuf不能正常使用;针对以上问题,修改了dcodeIO 的protobuf.js部分实现方式,以致微信小程序中运行protobuf.js。

安装以及使用

  • 1、首先下载本代码,将其中weichatPb文件夹加入到你的小程序项目中

  • 2、安装pbjs工具

    • 基于node.js,首先安装protobufjs
     $ npm install -g protobufjs
    

    会出现

     /usr/local/lib
     └─┬ [email protected] 
       ├── @protobufjs/[email protected] 
       ├── @protobufjs/[email protected] 
       ├── @protobufjs/[email protected] 
       ├── @protobufjs/[email protected] 
       ├── @protobufjs/[email protected] 
       ├── @protobufjs/[email protected] 
       ├── @protobufjs/[email protected] 
       ├── @protobufjs/[email protected] 
       ├── @protobufjs/[email protected] 
       ├── @protobufjs/[email protected] 
       ├── @types/[email protected] 
       ├── @types/[email protected] 
       └── [email protected] 
    
    

    证明安装成功

    • 接着安装 pbjs需要的库 命令行执行下“pbjs”就ok
     $ pbjs
    

    会出现

     -t, --target     Specifies the target format. Also accepts a path to require a custom target.
    
                    json          JSON representation
                    json-module   JSON representation as a module
                    proto2        Protocol Buffers, Version 2
                    proto3        Protocol Buffers, Version 3
                    static        Static code without reflection (non-functional on its own)
                    static-module Static code without reflection as a module
    
     -p, --path       Adds a directory to the include path.
    
     -o, --out        Saves to a file instead of writing to stdout.
    
     --sparse         Exports only those types referenced from a main file (experimental).
    
     Module targets only:
    
     -w, --wrap       Specifies the wrapper to use. Also accepts a path to require a custom wrapper.
    
                    	default   Default wrapper supporting both CommonJS and AMD
                    	commonjs  CommonJS wrapper
                    	amd       AMD wrapper
                    	es6       ES6 wrapper (implies --es6)
                    	closure   A closure adding to protobuf.roots where protobuf is a global
    
     --dependency     Specifies which version of protobuf to require. Accepts any valid module id
    
     -r, --root       Specifies an alternative protobuf.roots name.
    
     -l, --lint       Linter configuration. Defaults to protobuf.js-compatible rules:
    
                    	eslint-disable block-scoped-var, no-redeclare, no-control-regex, no-prototype-builtins
    
     --es6            	Enables ES6 syntax (const/let instead of var)
    
     Proto sources only:
    
     --keep-case      Keeps field casing instead of converting to camel case.
    
     Static targets only:
    
     --no-create      Does not generate create functions used for reflection compatibility.
     --no-encode      Does not generate encode functions.
     --no-decode      Does not generate decode functions.
     --no-verify      Does not generate verify functions.
     --no-convert     Does not generate convert functions like from/toObject
     --no-delimited   Does not generate delimited encode/decode functions.
     --no-beautify    Does not beautify generated code.
     --no-comments    Does not output any JSDoc comments.
    
     --force-long     Enfores the use of 'Long' for s-/u-/int64 and s-/fixed64 fields.
     --force-number   Enfores the use of 'number' for s-/u-/int64 and s-/fixed64 fields.
     --force-message  Enfores the use of message instances instead of plain objects.
     
    

    证明安装成功

  • 3、接下来我们使用pbjs 转换一下.proto文件

    • 我们先准备一份awesome.proto文件,内容如下
     // awesome.proto
     syntax = "proto3";
    
     message AwesomeMessage {
     	string awesome_field = 1; // becomes awesomeField
     }
     
    
    • 接下来我们来转换awesome.proto文件
     $ pbjs -t json awesome.proto > awesome.json
    
    • 这时我们会得到一个awesome.json文件,内容如下
     {
      "nested": {
      	"AwesomeMessage": {
       		"fields": {
         	  "awesomeField": {
           	   "type": "string",
           	   "id": 1
         	  }
       	   }
         }
       }
     }
    • 但此时的json文件我们不能直接使用,不过我们可以将json对象取出放到小程序项目当中去,比如在小程序项目中新建一个awesome.js,内容为
     module.exports = {
     	"nested": {
         	"AwesomeMessage": {
             	"fields": {
                 "awesomeField": {
                     "type": "string",
                     "id": 1
                }
             }
          }
        }
     };
  • 4、此时总算到我们使用该文件的时候了,我们在项目中新建一个js文件(需要在项目中require该文件),其内容如下

var protobuf = require('../weichatPb/protobuf.js'); //引入protobuf模块
var  awesomeConfig = require('./awesome.js');//加载awesome.proto对应的json
var AwesomeMessage = AwesomeRoot.lookupType("AwesomeMessage");//这就是我们的Message类

var payload = {awesomeField: "我是test1"};
var message = AwesomeMessage.create(payload);
var buffer = AwesomeMessage.encode(message).finish();
console.log("buffer", buffer);
var deMessage = AwesomeMessage.decode(buffer);
console.log("deMessage", deMessage);

结语

附件中有我的测试demo小程序编辑器打开后,直接在控制台就可以看到我的测试过程,测试代码在testProtocoBuffer.js中。 如果您对于该工具库有更好的提升欢迎提出,如果您在使用中发现bug或者有疑惑也可以反馈,我都会解答的 (^__^) 嘻嘻……

protobufferforwechat's People

Contributors

zhang19910325 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

protobufferforwechat's Issues

为什么对int64的解析不正确?

 let m = {
      requestType: RequestType["heartbeat"],
      requestParam: {
        // t: 1000000000000
        t: 1000
      }
    }
    let r = Request.create(m);
    let e = Request.encode(r).finish();
    console.log("编码:", m, "解码:", Request.decode(e))

    let m1 = {
      requestType: RequestType["heartbeat"],
      requestParam: {
        t: 1000000000000
        // t: 1000
      }
    }
    let r1 = Request.create(m1);
    let e1 = Request.encode(r1).finish();
    console.error("编码:", m1, "解码:", Request.decode(e1))

image

跪求 怎么解决这个问题

当 field为

"BaseReply":{
       "fields": {
           "spareParameter": {
            "keyType": "string",
            "type": "string",
            "id": 3
        },
   }
}

这种情况的时候 就会把spareParameter的map类型 解码成string了
跪求怎么解决这种问题

encode在模拟器正常,IOS手机上出问题

var buffer = msg.encode().finish();
console.log("buffer", buffer);
模拟器上输出的日志:
Uint8Array(92) [8, 1, 18, 88, 10, 14, 49, 56, 48, 46, 49, 53, 48, 46, 49, 56, 54, 46, 52, 50, 16, 168, 44, 26, 6, 104, 113, 121, 120, 109, 113, 34, 8, 49, 50, 51, 121, 120, 51, 50, 49, 42, 3, 47, 121, 120, 50, 20, 51, 95, 49, 53, 52, 49, 49, 52, 57, 49, 55, 54, 57, 51, 49, 50, 57, 55, 50, 56, 58, 20, 51, 95, 49, 53, 52, 49, 49, 52, 57, 49, 55, 54, 57, 51, 49, 50, 57, 55, 50, 56, 66, 0]
而在IOS的微信上输出:
复制不出来,我手动输入在手机看到的日志:
Object {"0": 8, "1": 1, "2": 18, "3": 88 ...
由于刚接触小程序和html5开发,是不是我犯了一个常识性错误,这种对象序列化我如何跨平台通过WSScocket传到服务器去正确解析?

不支持any类型

no such Type or Enum 'google.protobuf.Any' in Type 这个能不能支持一下any类型呀

在微信小程序中使用protobuf进行encode却得到了不同的buff

我是使用您的protobuf.js去解决在小程序中encode的问题,结果经过encode之后发现得到了不同的数据,这个是正常的WEB解析【使用了see: https://github.com/dcodeio/protobuf.js for details】https://raw.githubusercontent.com/keeplight-github/learngit/master/1.png
下面这个是异常的解析,可见得出了不同的数据
https://github.com/keeplight-github/learngit/blob/master/2.png?raw=true
劳驾您给看看

解析 uint64 类型

解析 uint64 类型 没有转化成具体的数值,而是 Long 对象类似 {low: 654, high: 0, unsigned: true} ,能在解析时直接转化为数值吗?

Message.decode 解析 MapFields 出错

例如:
map<string, string> spareParameter
如果 spareParameter为{cookie:'xxxx'} Message.decode解析为spareParameter:'xxxx'
如果 spareParameter为{} Message.decode解析为{}

发送的消息到nodejs服务器端解析异常

syntax = "proto2";

enum WSType {
MQInit = 1; // MQ 初始化
OnlineMsg = 2; // 在线消息
OfflineMsg = 3; // 离线消息
OnlineMsgList = 4; // 在线消息列表
OfflineMsgList = 5; // 离线消息列表
WSRESULTTYPE = 6;

}

message MQConfig {
required string host = 1; // MQ服务器域名
required int32 port = 2; // MQ服务器端口
required string user = 3; // MQ服务器用户名
required string pwd = 4; // MQ服务器密码
required string vhost = 5; // MQ服务器vhost路径
required string mqExchangeName = 6; // MQ在线分发Exchange名称
required string mqQueueName = 7; // MQ离线分发Queue名称
required string mqRoutingKey = 8; // MQ RoutingKey名称
}

message WsMessage {
required WSType type = 1; // 消息类型
optional MQConfig mqconfig = 2; // 如果type是MQInit;MQConfig信息放入此字段
}

代码:

var s = pkgMQInitMsg('1.1.1.1', '1', '1', '1', '1', '1', '1', '1');
var buffer = s.encode().finish();
//buffer[2] = 18;

printDump('encode s: ', s, buffer);
var deMessage = s.decode(buffer);
printDump('decode s', deMessage, buffer);

function pkgMQInitMsg(MqHost, MqPort, MqName, MqPwd, MqExchangeName, MqVHost, MqQueueName, MqRoutingKey) {

var wsmsg = WsMessage.create();
var mqconfig = MQConfig.create();
wsmsg.type = WSType.values.MQInit;
mqconfig.host = MqHost;
mqconfig.port = MqPort;
mqconfig.user = MqName;
mqconfig.pwd = MqPwd;
mqconfig.vhost = MqVHost;
mqconfig.mqExchangeName = MqExchangeName;
mqconfig.mqQueueName = MqQueueName;
mqconfig.mqRoutingKey = MqRoutingKey;
wsmsg.mqconfig = mqconfig;
return wsmsg;
}

小程序端序列化和反序列化都没有问题:
日志:[8, 1, 19, 29, 10, 7, 49, 46, 49, 46, 49, 46, 49, 16, 1, 26, 1, 49, 34, 1, 49, 42, 1, 49, 50, 1, 49, 58, 1, 49, 66, 1, 49]

但是在服务器端解析的时候异常:
AssertionError: Assertion failed
at new goog.asserts.AssertionError (/home/nodeproject/netwhiteboard/nodejs/node_modules/google-protobuf/google-protobuf.js:98:603)
at Object.goog.asserts.doAssertFailure_ (/home/nodeproject/netwhiteboard/nodejs/node_modules/google-protobuf/google-protobuf.js:99:126)
at Object.goog.asserts.assert (/home/nodeproject/netwhiteboard/nodejs/node_modules/google-protobuf/google-protobuf.js:99:385)
at jspb.BinaryReader.readMessage (/home/nodeproject/netwhiteboard/nodejs/node_modules/google-protobuf/google-protobuf.js:345:139)
at Function.proto.com.hengqian.whiteboard.msg.WsMessage.deserializeBinaryFromReader (/home/nodeproject/netwhiteboard/nodejs/whiteboardmsg_pb.js:4290:14)
at Function.proto.com.hengqian.whiteboard.msg.WsMessage.deserializeBinary (/home/nodeproject/netwhiteboard/nodejs/whiteboardmsg_pb.js:4266:54)
at InStream. (/home/nodeproject/netwhiteboard/nodejs/websockeMQ.js:22:49)
at emitNone (events.js:106:13)
at InStream.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)

上述日志异常位置是在解析WsMessage的第二个参数mqconfig时出现异常的。

同样的数据,如果我在html5页面生成的消息对象,只有第三位不一样,是18,不是19,如果我在小程序端手动把第三位调成18,服务器端解析没有问题
[8, 1, 19, 29, 10, 7, 49, 46, 49, 46, 49, 46, 49, 16, 1, 26, 1, 49, 34, 1, 49, 42, 1, 49, 50, 1, 49, 58, 1, 49, 66, 1, 49]

帮忙分析一下这个是什么原因?为什么第三位会有差异,这个和google protobuf格式有什么差异?

怎么使用google.protobuf.Any类型呀

message Response {
int32 command_id = 1;
int32 packet_id = 2;
google.protobuf.Any body = 3 ;
int32 err_code = 4;
string err_msg = 5;
}
会报错 Error: no such Type or Enum 'google.protobuf.Any' in Type .Response

pbjs的问题,为什么我没有pbjs -t

pbjs

Usage: pbjs [options] <schema_path>

Options:

-h, --help           output usage information
-V, --version        output the version number
--js <js_path>       Generate JavaScript code
--decode <msg_type>  Decode standard input to JSON
--encode <msg_type>  Encode standard input to JSON

发布到npm

微信小程序有越来越多能使用npm的场景了,比如mpvue, taro,还下载源码再使用体验比较差

.encode().finish().buffer的长度不对

var msg = pbmsg.encode().finish();
msg.length正确,msg.buffer的长度不对,始终是8192
此问题我通过var base64 = wx.arrayBufferToBase64(msg.buffer);的方式验证过,输出的base64长度不正常,同时,我从服务器端接收的到长度是8192
麻烦帮我看看是什么问题,多谢。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.