The official document: developers.google.com/protocol-bu… Protobuf github:github.com/protocolbuf…

First, basic knowledge

1.1 introduction

Protocol Buffers are a language-independent, platform-independent, extensible serialized structured data that stores data formats defined by a file suffix.proto. There are several ways to serialize structured data, such as XML and Json. Compared with XML and Json, Protocol buffers are smaller and faster to parse.

1.2 Protocol buffers syntax

Protocol buffers define a syntax for representing data: pb syntax; To name a few common ones:

Syntax = "proto2"; package com.bc.model.proto; option optimize_for = LITE_RUNTIME; // Message indicates the message object message User {// option indicates the optional string name = 1; optional int64 age = 2; }Copy the code

1.3 Protocol Buffers Data definition example

For example, for a User containing Name and Age: (1) can be expressed in XML as follows:


      
<User>
	<Name value = "jack"/>
	<Age value = 18 />
</User>
Copy the code

(2) Expressed in JSON as follows:

{
	"User": {
		"Name" : "Jack"."Age" : 18}}Copy the code

(3) When using Protocol buffers, first define the syntax format as follows:

syntax = "proto2"; package com.bc.model.proto; option optimize_for = LITE_RUNTIME; Message User {optional string name = 1; optional int64 age = 2; }Copy the code

The value of User is then set according to the platform code generated by the compiler:

UserModelProto.User.Builder builder = UserModelProto.User.Builder.newBuilder();
UserModelProto.User user = builder.setName("jack").setAge(18).build();
// Roles are passed to each other in byte arrays
byte[] byteArray = user.toByteArray();
Copy the code

1.4 Why is the performance good

(1) The tag-length-value and tag-value storage modes of the Protocol Buffer make the data storage more compact and reduce the use of delimiters; (2) The unique encoding method of the Protocol Buffer for data field values (Varint & Zigzag, etc.) reduces the number of bytes occupied by field values; (3) If the optional field in the Protocol Buffer is not set, it will not be encoded;

Protocol Buffers compiler

The Protocol buffers compiler is used to input the corresponding command on the command line and generate the corresponding platform (Java, c++, etc.) code or description file according to the Protocol buffer file.

2.1 Installation Procedure

  1. Download pb:developers.google.com/protocol-bu…
  2. The install. TXT file after the download describes the steps to install:
1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally,  type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory  by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution.Copy the code
  1. After the installation is successful, run protoc –version to view the version number.
>protoc --version
#Results:
>Libprotoc 2.5.0
Copy the code

2.2 Generate platform code

Proto file to generate object code. After installing the Protocol Buffer compiler, type the following command in shell:

#Usage:
#-i =proto File directory
#-- javA_out Specifies the Java object code folder to generate.
>protoc -I=/Users/bc/proto --java_out=/Users/bc/proto /Users/bc/proto/user_proto.proto
Copy the code

Protocol Buffers in Java

After generating the Java platform code with the Protocol Buffers compiler, you can copy the code to your project and use it as follows:

3.1 Adding a Dependency

Implementation 'com. Google. Protobuf: protobuf - Java: 2.7.0'Copy the code

3.2 Creating Protocol Buffers Data

UserModelProto.User.Builder builder = UserModelProto.User.Builder.newBuilder();
UserModelProto.User user = builder.setName("jack").setAge(18).build();
// Roles are passed to each other in byte arrays
byte[] byteArray = user.toByteArray();
Copy the code

3.3 Parsing Protocol buffers

// Suppose it is a byte array sent by another role
byte[] byteArray = getByteArray();
UserModelProto.User user = UserModelProto.User.parseFrom(byteArray);
Copy the code

4, Protocol buffers and Okhttp

4.1 Sending a Request

1. Create a user
val builder = UserModelProto.User.Builder.newBuilder();
val user = builder.setName("jack").setAge(18).build();
// 2. Create RequestBody **
val requestBody = RequestBody.create("application/x-protobuf", user.toByteArray())
// 3. Build okHttpClient
val okHttpClient = OkHttpClient.Builder()
    .connectionPool(ConnectionPool(2.35, TimeUnit.SECONDS))
    .connectTimeout(10, TimeUnit.SECONDS)
    .readTimeout(15, TimeUnit.SECONDS)
    .writeTimeout(15, TimeUnit.SECONDS)
    .build()
// 4. Build request and post(requestBody) **
val request = Request.Builder()
    .url("https://www.baidu.com").addHeader("COOKIE"."cookie").post(requestBody).build()

// 5. Send requests
okHttpClient.newCall(request).enqueue(object : Callback {
    override fun onFailure(call: Call, e: IOException) {
        TODO("Not yet implemented")}override fun onResponse(call: Call, response: Response) {
        TODO("Not yet implemented")}})Copy the code

4.2 Parsing the Request Result

The code to parse the result of the request is in onResponse() :

okHttpClient.newCall(request).enqueue(object : Callback {
	override fun onResponse(call: Call, response: Response) {
        ResponseBody responseBody = response.body();
        if (responseBody == null) {
        	return null;
    	}
   	 	BufferedSource bufferedSource = responseBody.source();
    	UserModelProto.User user = null;
   		if(bufferedSource ! =null) {
        	while(! bufferedSource.exhausted()) { user = UserModelProto.User.parseDelimitedFrom(bufferedSource.inputStream());if (protoResponse == null) {
        			break; }}}}override fun onFailure(call: Call, e: IOException) {
        TODO("Not yet implemented")}})Copy the code

5. Charles captured PB data

5.1 Generating a PB Description File

#Usage:
#-i =proto File directory
#-- Descriptor_set_out The path to generate the description file;
>protoc -I=/Users/bc/proto --descriptor_set_out=response_proto.desc response_proto.proto
Copy the code

5.2 Setting the PB Description File

Click on view-protobuf Settings in Charles… ; Then click Add to add the proto.desc file, as shown in the picture below:

5.3 Selecting Viewer Mappings

Click on the view-viewer Mappings inside Charles… ; Then select Enable Viewer Mapping and add the request to be mapped:The protocol buffer data in subsequent requests and returned results of the interface can be displayed.