• Protobuf入门


    这里我们尝试将Protobuf和RPC结合在一起使用,通过 Protobuf来最终保证RPC的接口规范和安全。
    Protobuf中最基本的数据单元是message,是类似Go语言中结构体的存在。在message中可以嵌套message或其他基础数据类型的成员。

    1. 首先创建hello.proto文件,其中包装HelloService服务中用到的字符串类型:
    2. 开头的syntax语句表示采用proto3的语法。第3版的Protobuf对语言进行了提炼简化,所有成员均采用类似Go语言中的零值初始化(不再支持自定义默认值),因此消息成员也不再需要支持required特性。需要加上option go_package="xxx/xxx" (随便写,最后会在这里生成.pb.go文件
      ),否则会说unable to determine the go import path.然后package指令指明当前是main包(这样可以与Go的包名一致,简化例子代码),当然用户也可以针对不同的语言来定制对应的包路径和名称。最后message关键字定义一个新的String类型,在最终生成的Go语言代码中对应一个String结构体。。String类型中只有一个字符串类型的value成员,该成员编码时用编号1代替名字。
    3. 在XML或JSON等数据描述语言中,一般通过成员的名字来绑定对应的数据。但是Protobuf编码却是通过成员的唯一编号来绑定数据,因此Protobuf编码后数据的体积会比较小,但是也不便于人们查阅。我们目前并不关注Protobuf的编码技术 ,最终生成的Go结构体可以自由采用JSON或Gob等编码格式,因此大家可以暂时忽略Protobuf的成员编码部分。
    4. Protobuf核心的工具集是用C++开发的,在官方的protoc编译器中并不支持Go语言。要想基于上面的hello.proto文件生成相应的Go代码,需要安装相应的插件。首先是安装官方的protoc工具,可以从Github官网下载(加压后将protoc.exe移动到%GOPATH%in下),然后是安装针对Go语言的代码生成插件,可以通过go get github.com/golang/protobuf/protoc-gen-go 命令安装(需要先安装有Git工具)。如果网络不好导致无法下载,到github.com/golang/protobuf,下载整个zip文件,解压,然后cd到protoc-gen-go文件夹中执行go build和go install即可(肯能需要配置代理,终端执行go env -w GOPROXY=https://goproxy.cn,direct),会在%GOPATH%in下生成一个exe文件,
      然后通过以下命令生成相应的Go代码:
      $ protoc --go_out=. hello.proto
      其中go_out参数告知protoc编译器去加载对应的protoc-gen-go工具,然后通过该工具生成代码放到当前目录。最后是一系列要处理的Protobuf文件的列表。
    5. 这里只生成了一个hello.pb.go文件,其中String结构体内容如下:
    type String struct {
    	state         protoimpl.MessageState
    	sizeCache     protoimpl.SizeCache
    	unknownFields protoimpl.UnknownFields
    
    	Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
    }
    
    func (x *String) Reset() {
    	*x = String{}
    	if protoimpl.UnsafeEnabled {
    		mi := &file_hello_proto_msgTypes[0]
    		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
    		ms.StoreMessageInfo(mi)
    	}
    }
    
    func (x *String) String() string {
    	return protoimpl.X.MessageStringOf(x)
    }
    
    func (*String) ProtoMessage() {}
    
    func (x *String) ProtoReflect() protoreflect.Message {
    	mi := &file_hello_proto_msgTypes[0]
    	if protoimpl.UnsafeEnabled && x != nil {
    		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
    		if ms.LoadMessageInfo() == nil {
    			ms.StoreMessageInfo(mi)
    		}
    		return ms
    	}
    	return mi.MessageOf(x)
    }
    
    // Deprecated: Use String.ProtoReflect.Descriptor instead.
    func (*String) Descriptor() ([]byte, []int) {
    	return file_hello_proto_rawDescGZIP(), []int{0}
    }
    
    func (x *String) GetValue() string {
    	if x != nil {
    		return x.Value
    	}
    	return ""
    }
    

    此处隐藏了一些以xxx_为名字前缀的成员,ProtoMessage()方法表示这是一个实现了proto.Message接口的方法。此外,Protobuf还为每一个成员生成了一个Get方法,Get方法不仅可以处理空指针类型, 而且可以与Protobuf第二版的方法保持一致。
    6. 基于新的String类型,我们可以重新实现HelloService服务:

    type HelloService struct{}
    func(p *HelloService) Hello(request *String, reply *String) error{
      reply.Value = "hello:"+request.GetValue()
      return nil
    }
    
    1. 其中Hello方法的输入参数和输出参数均改为Protobuf定义的String类型表示。因为新的输入参数为结构体类型,所以改用指针类型作为输入参数,函数内部的代码同时也做了相应的调整。下面更新hello.proto文件,通过Protobuf来定义HelloService服务:
    service HelloService{
      rpc Hello (String) returns (String);
    }
    
  • 相关阅读:
    假脱机技术
    HTTP报文
    字符串转换成浮点数的方法
    表变量与临时表空间
    规范浮点数
    什么是批处理
    浅谈性能测试、压力测试和负载测试
    关于CSDN的一个安全漏洞
    HttpWatch7.0测试工具
    vbscript能做什么
  • 原文地址:https://www.cnblogs.com/pangqianjin/p/14618031.html
Copyright © 2020-2023  润新知