• Go 支持Protocol Buffers的配置


    安装

    protoc (The protocol compiler)是由C++写的,支持的 C++、Java、Python、Objective-C、C#、JavaNano、JavaScript、Ruby、PHP 的实现都在 https://github.com/google/protobuf 这个项目中, 例外的是 Go 的实现是在 https://github.com/golang/protobuf 这里。

    所以Go 支持 Protocol Buffers的安装需要下面三步:

    • Install the standard C++ implementation of protocol buffers from https://developers.google.com/protocol-buffers/ 。如果不想源码编译的话,可以直接下载对应操作系统对应的 protoc https://github.com/google/protobuf/releases, 参考 : https://github.com/google/protobuf/releases 
    • Of course, install the Go compiler and tools from https://golang.org/ See https://golang.org/doc/install for details or, if you are using gccgo, follow the instructions at https://golang.org/doc/install/gccgo   安装Go的开发编译环境。
    • Grab the code from the repository and install the proto package. The simplest way is to run go get -u github.com/golang/protobuf/{proto,protoc-gen-go}. The compiler plugin, protoc-gen-go, will be installed in $GOBIN, defaulting to $GOPATH/bin. It must be in your $PATH for the protocol compiler, protoc, to find it.通过go get -u github.com/golang/protobuf/{proto,protoc-gen-go}  获得go的插件包,并完成 protoc-gen-go 的编译。protoc-gen-go 默认会编译到 $GOPATH/bin 目录下, 这个目录需要放入$PATH 中,方便 protoc 找到 protoc-gen-go 。

     

    https://github.com/golang/protobuf 这里其实包含两部分功能:

    • a 'protocol compiler plugin' that generates Go source files that, once compiled, can access and manage protocol buffers;  Protoc编译插件,产生Go的源码。
    • a library that implements run-time support for encoding (marshaling), decoding (unmarshaling), and accessing protocol buffers. 运行时支持库,包括编码、解码、访问PB内容的功能库。

     

    使用 protoc

    把 proto 文件编译成 go 源码的命令如下:

    $ protoc --go_out=./go/ ./proto/helloworld.proto

    参考: http://www.cnblogs.com/ghj1976/p/5435565.html 

    如果我们需要生产 gRPC 使用的代码, 则需要是下面的命令:

    $ protoc --go_out=plugins=grpc:./go/ ./proto/helloworld.proto

    注意这类表明了 plugins=grpc,

    按照这种方式生成的代码,会多 客户端和服务器端的通用代码,方便我们建立客户端和服务器端的服务。

    下面是使用helloworld.proto 产生的 grpc 使用的源码, 比不带 grpc的要多一部分代码。

    // Code generated by protoc-gen-go.
    // source: proto/helloworld.proto
    // DO NOT EDIT!

    /*
    Package helloworld is a generated protocol buffer package.

    It is generated from these files:
        proto/helloworld.proto

    It has these top-level messages:
        HelloRequest
        HelloReply
    */
    package helloworld

    import proto "github.com/golang/protobuf/proto"
    import fmt "fmt"
    import math "math"

    import (
        context "golang.org/x/net/context"
        grpc "google.golang.org/grpc"
    )

    // Reference imports to suppress errors if they are not otherwise used.
    var _ = proto.Marshal
    var _ = fmt.Errorf
    var _ = math.Inf

    // This is a compile-time assertion to ensure that this generated file
    // is compatible with the proto package it is being compiled against.
    const _ = proto.ProtoPackageIsVersion1

    // The request message containing the user's name.
    type HelloRequest struct {
        Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
    }

    func (m *HelloRequest) Reset()                    { *m = HelloRequest{} }
    func (m *HelloRequest) String() string            { return proto.CompactTextString(m) }
    func (*HelloRequest) ProtoMessage()               {}
    func (*HelloRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }

    // The response message containing the greetings
    type HelloReply struct {
        Message string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"`
    }

    func (m *HelloReply) Reset()                    { *m = HelloReply{} }
    func (m *HelloReply) String() string            { return proto.CompactTextString(m) }
    func (*HelloReply) ProtoMessage()               {}
    func (*HelloReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }

    func init() {
        proto.RegisterType((*HelloRequest)(nil), "helloworld.HelloRequest")
        proto.RegisterType((*HelloReply)(nil), "helloworld.HelloReply")
    }

    // Reference imports to suppress errors if they are not otherwise used.
    var _ context.Context
    var _ grpc.ClientConn

    // This is a compile-time assertion to ensure that this generated file
    // is compatible with the grpc package it is being compiled against.
    const _ = grpc.SupportPackageIsVersion2

    // Client API for Greeter service

    type GreeterClient interface {
        // Sends a greeting
        SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error)
    }

    type greeterClient struct {
        cc *grpc.ClientConn
    }

    func NewGreeterClient(cc *grpc.ClientConn) GreeterClient {
        return &greeterClient{cc}
    }

    func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) {
        out := new(HelloReply)
        err := grpc.Invoke(ctx, "/helloworld.Greeter/SayHello", in, out, c.cc, opts...)
        if err != nil {
            return nil, err
        }
        return out, nil
    }

    // Server API for Greeter service

    type GreeterServer interface {
        // Sends a greeting
        SayHello(context.Context, *HelloRequest) (*HelloReply, error)
    }

    func RegisterGreeterServer(s *grpc.Server, srv GreeterServer) {
        s.RegisterService(&_Greeter_serviceDesc, srv)
    }

    func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
        in := new(HelloRequest)
        if err := dec(in); err != nil {
            return nil, err
        }
        if interceptor == nil {
            return srv.(GreeterServer).SayHello(ctx, in)
        }
        info := &grpc.UnaryServerInfo{
            Server:     srv,
            FullMethod: "/helloworld.Greeter/SayHello",
        }
        handler := func(ctx context.Context, req interface{}) (interface{}, error) {
            return srv.(GreeterServer).SayHello(ctx, req.(*HelloRequest))
        }
        return interceptor(ctx, in, info, handler)
    }

    var _Greeter_serviceDesc = grpc.ServiceDesc{
        ServiceName: "helloworld.Greeter",
        HandlerType: (*GreeterServer)(nil),
        Methods: []grpc.MethodDesc{
            {
                MethodName: "SayHello",
                Handler:    _Greeter_SayHello_Handler,
            },
        },
        Streams: []grpc.StreamDesc{},
    }

    var fileDescriptor0 = []byte{
        // 183 bytes of a gzipped FileDescriptorProto
        0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0x2b, 0x28, 0xca, 0x2f,
        0xc9, 0xd7, 0xcf, 0x48, 0xcd, 0xc9, 0xc9, 0x2f, 0xcf, 0x2f, 0xca, 0x49, 0xd1, 0x03, 0x0b, 0x08,
        0x71, 0x21, 0x44, 0x94, 0x94, 0xb8, 0x78, 0x3c, 0x40, 0xbc, 0xa0, 0xd4, 0xc2, 0xd2, 0xd4, 0xe2,
        0x12, 0x21, 0x21, 0x2e, 0x96, 0xbc, 0xc4, 0xdc, 0x54, 0x09, 0x46, 0x05, 0x46, 0x0d, 0xce, 0x20,
        0x30, 0x5b, 0x49, 0x8d, 0x8b, 0x0b, 0xaa, 0xa6, 0x20, 0xa7, 0x52, 0x48, 0x82, 0x8b, 0x3d, 0x37,
        0xb5, 0xb8, 0x38, 0x31, 0x1d, 0xa6, 0x08, 0xc6, 0x35, 0xf2, 0xe4, 0x62, 0x77, 0x2f, 0x4a, 0x4d,
        0x2d, 0x49, 0x2d, 0x12, 0xb2, 0xe3, 0xe2, 0x08, 0x4e, 0xac, 0x04, 0xeb, 0x12, 0x92, 0xd0, 0x43,
        0x72, 0x01, 0xb2, 0x65, 0x52, 0x62, 0x58, 0x64, 0x80, 0x56, 0x28, 0x31, 0x38, 0x99, 0x71, 0x49,
        0x67, 0xe6, 0xeb, 0xa5, 0x17, 0x15, 0x24, 0xeb, 0xa5, 0x56, 0x24, 0xe6, 0x16, 0xe4, 0xa4, 0x16,
        0x23, 0xa9, 0x75, 0xe2, 0x07, 0x2b, 0x0e, 0x07, 0xb1, 0x03, 0x40, 0x5e, 0x0a, 0x60, 0x5c, 0xc4,
        0xc4, 0xec, 0xe1, 0x13, 0x9e, 0xc4, 0x06, 0xf6, 0xa1, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x3e,
        0x3f, 0x8e, 0x69, 0xfb, 0x00, 0x00, 0x00,
    }

    protoc-gen-go 的一些特有的参数如下:

    命令格式:

    protoc --go_out=plugins=grpc,import_path=mypackage:. *.proto
    • import_prefix=xxx - a prefix that is added onto the beginning of all imports. Useful for things like generating protos in a subdirectory, or regenerating vendored protobufs in-place.    import 的前缀,当产生protos在一个子目录时有用。
    • import_path=foo/bar - used as the package if no input files declare go_package. If it contains slashes, everything up to the rightmost slash is ignored.没有定义 go_package 时的包名。 
    • plugins=plugin1+plugin2 - specifies the list of sub-plugins to load. The only plugin in this repo is grpc.  插件名,这里只有一个插件 grpc
    • Mfoo/bar.proto=quux/shme - declares that foo/bar.proto is associated with Go package quux/shme. This is subject to the import_prefix parameter. 定义proto文件跟包的映射关系。

     

    参考资料:

    https://github.com/golang/protobuf

  • 相关阅读:
    Git_学习_01_ 常用 Git 命令清单
    Git_错误_03_ Git提交时显示用户 unknown
    Java微信小程序开发_00_资源帖
    Git_错误_02_error: src refspec master does not match any
    Java企业微信开发_08_素材管理之下载微信临时素材到本地服务器
    Java企业微信开发_07_JSSDK多图上传
    Java企业微信开发_07_总结一下企业微信的配置
    Java_数据交换_dom4j_01_解析xml
    Git_学习_00_资源帖
    小结:线段树 & 主席树 & 树状数组
  • 原文地址:https://www.cnblogs.com/ghj1976/p/5439283.html
Copyright © 2020-2023  润新知