标签 - Protobuf

Protobuf    2019-08-26 14:54:40    12    0    0

protobuf 是做什么的
专业的解答:
Protocol Buffers 是一种轻便高效的结构化数据存储格式,可用于结构化数据串行化,很适合做数据存储或 RPC 数据交换格式。它可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。简单的说就是干和xml一样的事,把某种数据结构的信息,以某种格式保存起来。主要用于数据存储、传输协议格式等场合

了解了下这种数据格式使用的场景。

1、RPC序列化,转自:http://blog.leanote.com/post/weibo-007/f40e8fee0dfb
在PRC框架中,数据的传输发生在客户端和服务端,而我们知道基于TCP协议最终传输的是二进制的0/1序列。所以,基于TCP传输协议的RPC服务自然也需要将数据结构转换成二进制,和二进制转换成数据结构的功能。所以,原则上,基于网络的数据传输只能传输二进制表示的字符串
但是,传输的二进制序列是完全没有意义的,除非有一套解析二进制串的协议。没错,这个协议可以就是目前我们大家熟知的xml,json协议。当然。除了这两者,还有其他的的序列化和反序列化协议。

XMl
<note>
<to>George</to>
<from>John</from>
<msg>Don't forget the meeting!</msg>
</note>

可以看出这种序列化协议的优点是可读性和易调试行。但是这种协议的缺点也很明显:额外空间开销大,序列化之后的数据量剧增。

JSON
{
"to":"George",
"from":"John",
"msg":"Don't forget the meeting!"
}

这种序列化协议有很大的优势:
1. 这样表示非常符合工程师对对象的理解,尤其是js工程师
2. 和xml一样,可读性强
3. 和xml相比,更加节省空间,解析速度更快
4. 由于天生的Web友好型,JSON自然而然成了AJAX数据传输的标准协议。JSON目前的使用非常广泛,但是,如果数据传输和响应时间有跟苛刻的要求,那么JSON可能性能还是差点。

Protobuf (Google Protocol Buffer)数据结构定义文件的格式如下:
syntax = "proto3";
package config;
message MailConfig{
string to = 1;
string from

GO Protobuf    2019-08-26 14:12:37    148    0    0
  1. package main
  2.  
  3. import (
  4.    "github.com/golang/protobuf/proto"
  5.    "git.dllhook.com/protobuf_test/proto"
  6.    "log"
  7.    "fmt"
  8.    "encoding/json"
  9. )
  10.  
  11. func JSON2PB(form_json_str string, to_pb proto.Message) error {
  12.    // json字符串转pb
  13.    return json.Unmarshal([]byte(form_json_str), &to_pb)
  14. }
  15.  
  16. func PB2JSON(from_pb proto.Message, to_json_str string) error {
  17.    // pb转json字符串
  18.    json_str, err := json.Marshal(from_pb)
  19.    if err == nil {
  20.       to_json_str = string(json_str)
  21.    }
  22.  
  23.    return err
  24. }
  25.  
  26. func main() {
  27.    ///////////////////////////////////////////////////////////////////////////////////////////
  28.    /* -- 直接对pb赋值
  29.    deviceInfo := example.DeviceInfo{
  30.       DeviceName: proto.String("PiaoYun iPhone"),
  31.       DeviceType: proto.String("iPhone"),
  32.       SystemVersion: proto.String("9.0.2"),
  33.    }
  34.    */
  35.  
  36.    // json转pb
  37.    json_str := `{"DeviceName":"PiaoYun iPhone","DeviceType":"iPhone","SystemVersion":"9.0.2"}`
  38.    var deviceInfo www_dllhook_com.DeviceInfo
  39.    err := JSON2PB(json_str, &deviceInfo)
  40.    fmt.Println(err)
  41.    /////////////////////
Android Protobuf    2019-07-09 18:25:35    38    0    0

简介

Google Protocol Buffers 简称 Protobuf,类似 json 或 XML,是一种序列化结构数据的机制,但是比它们更小、更快、更简单。同时支持多语言,跨平台。
目前主要有两个大版本:proto2 和 proto3。
其中 proto2 支持 Java、Python、 Objective-C、和 C++
proto3 增加了对Go、JavaNano、Ruby、和 C#的支持。

proto例子

syntax = "proto3";
package tutorial;

import "google/protobuf/timestamp.proto";

option java_package = "com.katyusha.aron.demo";
option java_outer_classname = "AddressBookProtos";

message Person {
    string name = 1;
    int32 id = 2;
    string email = 3;

    enum PhoneType{
        MOBILE = 0;
        HOME = 1;
        WORK = 2;
    }

    message PhoneNumber {
        string number = 1;
        PhoneType type = 2;
    }

    repeated PhoneNumber phone = 4;

}

message AddressBook {
    repeated Person person = 1;
}

Protobuf使用.proto文件来定义数据格式,并同时提供编译器将这些文件编译为各种语言的源码。
message 格式非常简单。每种类型的 message 包含一个或者多个唯一编码字段,每个字段由名称和值类型组成,值类型可以是数字(整形或者浮点型)、布尔值、字符串、原始字节,甚至是其他的 message(如上例所示)。Protobuf 允许 message 中包含 message,以达到分层嵌套。
值得注意的一点是,每个属性都有唯一的一个tag,上面的0,1,2...等,这些tag非常重要,是 Prodobuf 编码时

Protobuf    2019-04-28 09:45:09    13    0    0

Protobuf是什么

Protobuf是一种平台无关、语言无关、可扩展且轻便高效的序列化数据结构的协议,可以用于网络通信数据存储

为什么要使用Protobuf

 
protobuf特点.png

如何使用Protobuf

protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/addressbook.proto

-I 编译源文件的目录

--java_out 编译目录文件

通过这个命令会自动编译出java代码,目前protobuf支持以下语言

LanguageSource
C++src
Javajava
Pythonpython
Objective-Cobjectivec
C#csharp
JavaNanojavanano
JavaScriptjs
Rubyruby
Gogolang/protobuf
PHPphp
Dartdart-lang/protobuf

由于命令行的方式编译代码非常繁琐,且效率极低。谷歌提供了开源的Protobuf Gradle插件

简单说一下配置方式

在project.gradle中配置

buildscript {
  repositories {
    mavenLocal()
  }
  dependencies {
    classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.6-SNAPSHOT'
  }
}

在modle.gradle中配置

apply plugin: 'com.google.protobuf'

dependencies {
  // You need to depend on the lite runtime library, not protobuf-java
  compile 'com.google.protobuf:protobuf-lite:3.0.0'
}

protobuf {
  protoc {
    // You still need protoc like in the non-Android case
    artifact = 'com.google.protobuf:protoc:3.0.0'
  }
  plugins {
    javalite {
      // The codegen for lite comes a
PHP Protobuf    2019-04-25 10:01:59    17    0    0

下载代码

 git clone https://github.com/protocolbuffers/protobuf.git

安装protobuf:

./autogen.sh
./configure --prefix=/usr/local/protobuf
make
sudo make install

安装php扩展:

cd protobuf/php/ext/google/protobuf
/usr/local/php-7.1.11/bin/phpize
./configure --with-php-config=/usr/local/php-7.1.11/bin/php-config
make
sudo make install

添加配置:

/usr/local/php-7.1.11/bin/php --ini | grep php.ini
sudo vim  /usr/local/php-7.1.11/etc/php.ini
extension=protobuf.so

测试:

编写proto 协议文件

vim User.proto

syntax="proto3";
message UserInfo
{
int32 id = 1;
string name = 2;
}

用protoc编译协议文件,会在当前目录下生成GPBMetadata目录和UserInfo.php文件

/usr/local/protobuf/bin/protoc --php_out=./ User.proto

安装php库:

composer require google/protobuf

编写php脚本

<?php

require('./vendor/autoload.php');
require('./UserInfo.php');
require('./GPBMetadata/User.php');

$pbUserInfo = new UserInfo();
$pbUserInfo->setId(1001);
$pbUserInfo->setName('jack');
$str = $pbUserInfo->serializeToString();

$ptTempUser = new UserInfo();
$ptTempUser->mergeFromString($str);
var_dump("id:".$