前言

protobuf是二进制协议,传输效率极高,传输体积很小,在tcp/rpc里的使用很普及。

使用须知

proto.Marshal()
protoc.exeproto-gen-go.exeprotoc --version
gitgit --version
go version

环境安装好了以后,需要知道如何书写proto文件。想要一概而精是不正常的,我们来通过需求来学习最佳。

安装protoc与proto-gen-go

protoc: https://github.com/golang/protobuf

proto-gen-go:https://github.com/golang/protobuf/tree/master/protoc-gen-go

cd %GOPATH%cd /src/github.com/golanggit clone https://github.com/golang/protobuf.git protobuf
%GOPATH%/src/github.com/golang/protobuf
https://github.com/protocolbuffers/protobuf/releaseswin64%GOPATH%\bin%GOPATH%\src\github.com\golang\protobuf\protoc-gen-gogo build -o protoc-gen-go.exe%GOPATH%\bin%GOPATH%\bin

生成go model

cd /x/x/m.proto
protoc --go_out=. m.proto

小试牛刀

mkdir pbcd pb
syntax = "proto3";
package pb;

message User {
   int32 id = 1;
   string username = 2;
}
protoc --go_out=plugins=grpc:. hello.proto

至此,go file已经自动生成了

小试牛刀,使用marshal和unmarshal

package main

import (
	"fmt"
	"github.com/golang/protobuf/proto"
	"t/pb"
)

func main() {
    buf , e:= proto.Marshal(&pb.User{
    	Id: 1,
    	Username: "csdn",
	})

    if e!=nil {
    	panic(e)
	}

    fmt.Println(buf)
    var tmp pb.User
    e = proto.Unmarshal(buf, &tmp)
	if e!=nil {
		panic(e)
	}
    fmt.Println(tmp)
}

几个常用的protoc命令:

protoc --go_out=plugins=grpc:. example.protoprotoc --go_out=plugins=micro:. hello_world.protoprotoc --go_out=plugins=grpc:. -I=${GOPATH}/src -I=. xxx.proto/.GOPATH/src

常见错误

  1. unknow service xxxx
    可能是服务端和客户端的proto文件不一致,自动生成的代码存在误差,需要重新同步

注意

  1. proto文件里的package,必须统一。出错场景:服务端的proto文件共享给客户端,客户端复制一份一样的proto文件后,将内容package修改成了其它名字,将造成服务不识别。