当前位置:网站首页>protobuf与grpc
protobuf与grpc
2022-07-03 13:40:00 【天龙至尊】
protobuf的使用:
这里介绍protobuf的工具的下载与使用,以及结合grpc进行微服务框架的编写!!!
protoc的程序的下载链接如下:
Releases · protocolbuffers/protobuf · GitHubProtocol Buffers - Google's data interchange format - Releases · protocolbuffers/protobuf
https://github.com/protocolbuffers/protobuf/releases选择对应的操作系统类型的protoc下载即可!!!
这里需要:github.com/golang/protobuf/protoc-gen-go这个库
GitHub - golang/protobuf: Go support for Google's protocol buffersGo support for Google's protocol buffers. Contribute to golang/protobuf development by creating an account on GitHub.
https://github.com/golang/protobuf
需要注意的是:
protoc的版本要和protoc-gen-go的版本要一致才行,不然生成出来的代码会出错!!!
go get github.com/golang/protobuf/protoc-gen-go编写proto文件:
helloworld.proto:
syntax = "proto3";
option go_package = "./";
message HelloRequest{
string name = 1;
int32 age = 2;
repeated string courses = 3;
}要想使用protoc这个程序,需要进行环境变量的配置;环境变量的配置无论是在windows、macOs、Linux的都不具体说明了。
配置好protoc的环境变量后,我们就可以在全局使用protoc这个命令了!
protoc -I . helloworld.proto --go_out=plugins=grpc:.这样会生成一个helloworld.pb.go的文件:
helloworld.pb.go:
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.21.2
// source: helloworld.proto
package protobuf
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type HelloRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Age int32 `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"`
Courses []string `protobuf:"bytes,3,rep,name=courses,proto3" json:"courses,omitempty"`
}
func (x *HelloRequest) Reset() {
*x = HelloRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_helloworld_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *HelloRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*HelloRequest) ProtoMessage() {}
func (x *HelloRequest) ProtoReflect() protoreflect.Message {
mi := &file_helloworld_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 HelloRequest.ProtoReflect.Descriptor instead.
func (*HelloRequest) Descriptor() ([]byte, []int) {
return file_helloworld_proto_rawDescGZIP(), []int{0}
}
func (x *HelloRequest) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *HelloRequest) GetAge() int32 {
if x != nil {
return x.Age
}
return 0
}
func (x *HelloRequest) GetCourses() []string {
if x != nil {
return x.Courses
}
return nil
}
var File_helloworld_proto protoreflect.FileDescriptor
var file_helloworld_proto_rawDesc = []byte{
0x0a, 0x10, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x22, 0x4e, 0x0a, 0x0c, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x05, 0x52, 0x03, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x72,
0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x72, 0x73,
0x65, 0x73, 0x42, 0x04, 0x5a, 0x02, 0x2e, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_helloworld_proto_rawDescOnce sync.Once
file_helloworld_proto_rawDescData = file_helloworld_proto_rawDesc
)
func file_helloworld_proto_rawDescGZIP() []byte {
file_helloworld_proto_rawDescOnce.Do(func() {
file_helloworld_proto_rawDescData = protoimpl.X.CompressGZIP(file_helloworld_proto_rawDescData)
})
return file_helloworld_proto_rawDescData
}
var file_helloworld_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_helloworld_proto_goTypes = []interface{}{
(*HelloRequest)(nil), // 0: HelloRequest
}
var file_helloworld_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_helloworld_proto_init() }
func file_helloworld_proto_init() {
if File_helloworld_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_helloworld_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HelloRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_helloworld_proto_rawDesc,
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_helloworld_proto_goTypes,
DependencyIndexes: file_helloworld_proto_depIdxs,
MessageInfos: file_helloworld_proto_msgTypes,
}.Build()
File_helloworld_proto = out.File
file_helloworld_proto_rawDesc = nil
file_helloworld_proto_goTypes = nil
file_helloworld_proto_depIdxs = nil
}
测试protobuf的压缩率与json的对比:
package main
import (
"encoding/json"
"fmt"
"github.com/golang/protobuf/proto"
"go-micro-service-architect/cn/ljxwtl/micro/rpc_service_new/protobuf"
)
type Hello struct {
Name string `json:"name"`
Age int32 `json:"age"`
Courses []string `json:"courses"`
}
func main() {
var request = protobuf.HelloRequest{
Name: "bobby",
Age: 30,
Courses: []string{"go", "java", "python"},
}
bytes, _ := proto.Marshal(&request)
fmt.Println(len(bytes), bytes)
var hello = &Hello{
Name: "bobby",
Age: 30,
Courses: []string{"go", "java", "python"},
}
marshal, _ := json.Marshal(hello)
fmt.Println(len(marshal))
var targetReq = new(protobuf.HelloRequest)
_ = proto.Unmarshal(bytes, targetReq)
fmt.Println(targetReq)
}

几乎是两倍多的对比。
grpc的使用:
helloworld.proto:
syntax = "proto3";
option go_package = "./;protobuf";
service Greeter{
rpc SayHello(HelloRequest) returns (HelloResponse);
}
message HelloRequest{
string name = 1;
int32 age = 2;
repeated string courses = 3;
}
message HelloResponse{
string reply = 1;
}运行命令:
protoc -I . helloworld.proto --go_out=plugins=grpc:.就会生成如下的代码:
helloworld.pb.go:
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.21.2
// source: helloworld.proto
package protobuf
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type HelloRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Age int32 `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"`
Courses []string `protobuf:"bytes,3,rep,name=courses,proto3" json:"courses,omitempty"`
}
func (x *HelloRequest) Reset() {
*x = HelloRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_helloworld_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *HelloRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*HelloRequest) ProtoMessage() {}
func (x *HelloRequest) ProtoReflect() protoreflect.Message {
mi := &file_helloworld_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 HelloRequest.ProtoReflect.Descriptor instead.
func (*HelloRequest) Descriptor() ([]byte, []int) {
return file_helloworld_proto_rawDescGZIP(), []int{0}
}
func (x *HelloRequest) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *HelloRequest) GetAge() int32 {
if x != nil {
return x.Age
}
return 0
}
func (x *HelloRequest) GetCourses() []string {
if x != nil {
return x.Courses
}
return nil
}
type HelloResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Reply string `protobuf:"bytes,1,opt,name=reply,proto3" json:"reply,omitempty"`
}
func (x *HelloResponse) Reset() {
*x = HelloResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_helloworld_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *HelloResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*HelloResponse) ProtoMessage() {}
func (x *HelloResponse) ProtoReflect() protoreflect.Message {
mi := &file_helloworld_proto_msgTypes[1]
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 HelloResponse.ProtoReflect.Descriptor instead.
func (*HelloResponse) Descriptor() ([]byte, []int) {
return file_helloworld_proto_rawDescGZIP(), []int{1}
}
func (x *HelloResponse) GetReply() string {
if x != nil {
return x.Reply
}
return ""
}
var File_helloworld_proto protoreflect.FileDescriptor
var file_helloworld_proto_rawDesc = []byte{
0x0a, 0x10, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x22, 0x4e, 0x0a, 0x0c, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x05, 0x52, 0x03, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x72,
0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x72, 0x73,
0x65, 0x73, 0x22, 0x25, 0x0a, 0x0d, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x70, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x05, 0x72, 0x65, 0x70, 0x6c, 0x79, 0x32, 0x34, 0x0a, 0x07, 0x47, 0x72, 0x65,
0x65, 0x74, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x08, 0x53, 0x61, 0x79, 0x48, 0x65, 0x6c, 0x6c, 0x6f,
0x12, 0x0d, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x0e, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42,
0x0d, 0x5a, 0x0b, 0x2e, 0x2f, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_helloworld_proto_rawDescOnce sync.Once
file_helloworld_proto_rawDescData = file_helloworld_proto_rawDesc
)
func file_helloworld_proto_rawDescGZIP() []byte {
file_helloworld_proto_rawDescOnce.Do(func() {
file_helloworld_proto_rawDescData = protoimpl.X.CompressGZIP(file_helloworld_proto_rawDescData)
})
return file_helloworld_proto_rawDescData
}
var file_helloworld_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_helloworld_proto_goTypes = []interface{}{
(*HelloRequest)(nil), // 0: HelloRequest
(*HelloResponse)(nil), // 1: HelloResponse
}
var file_helloworld_proto_depIdxs = []int32{
0, // 0: Greeter.SayHello:input_type -> HelloRequest
1, // 1: Greeter.SayHello:output_type -> HelloResponse
1, // [1:2] is the sub-list for method output_type
0, // [0:1] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_helloworld_proto_init() }
func file_helloworld_proto_init() {
if File_helloworld_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_helloworld_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HelloRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_helloworld_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HelloResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_helloworld_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_helloworld_proto_goTypes,
DependencyIndexes: file_helloworld_proto_depIdxs,
MessageInfos: file_helloworld_proto_msgTypes,
}.Build()
File_helloworld_proto = out.File
file_helloworld_proto_rawDesc = nil
file_helloworld_proto_goTypes = nil
file_helloworld_proto_depIdxs = nil
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConnInterface
// 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.SupportPackageIsVersion6
// GreeterClient is the client API for Greeter service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type GreeterClient interface {
SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloResponse, error)
}
type greeterClient struct {
cc grpc.ClientConnInterface
}
func NewGreeterClient(cc grpc.ClientConnInterface) GreeterClient {
return &greeterClient{cc}
}
func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloResponse, error) {
out := new(HelloResponse)
err := c.cc.Invoke(ctx, "/Greeter/SayHello", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// GreeterServer is the server API for Greeter service.
type GreeterServer interface {
SayHello(context.Context, *HelloRequest) (*HelloResponse, error)
}
// UnimplementedGreeterServer can be embedded to have forward compatible implementations.
type UnimplementedGreeterServer struct {
}
func (*UnimplementedGreeterServer) SayHello(context.Context, *HelloRequest) (*HelloResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented")
}
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: "/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: "Greeter",
HandlerType: (*GreeterServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "SayHello",
Handler: _Greeter_SayHello_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "helloworld.proto",
}
编写Server端:
server.go:
package main
import (
"context"
"fmt"
"go-micro-service-architect/cn/ljxwtl/micro/rpc_service_new/protobuf"
"google.golang.org/grpc"
"net"
)
type Server struct {
}
func (s *Server) SayHello(ctx context.Context, in *protobuf.HelloRequest) (*protobuf.HelloResponse, error) {
return &protobuf.HelloResponse{
Reply: "hello===>>>" + in.Name,
}, nil
}
func main() {
server := grpc.NewServer()
protobuf.RegisterGreeterServer(server, &Server{})
listen, err := net.Listen("tcp", "0.0.0.0:8080")
if err != nil {
fmt.Println(err.Error())
}
err = server.Serve(listen)
if err != nil {
fmt.Println(err.Error())
}
}
客户端代码:
client.go:
package main
import (
"context"
"fmt"
"go-micro-service-architect/cn/ljxwtl/micro/rpc_service_new/protobuf"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
func main() {
conn, err := grpc.Dial("127.0.0.1:8080", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
panic(err)
}
defer conn.Close()
client := protobuf.NewGreeterClient(conn)
response, err := client.SayHello(context.Background(), &protobuf.HelloRequest{
Name: "test test",
})
fmt.Println(response.Reply)
}
请求客户端执行:

边栏推荐
- QT learning 23 layout manager (II)
- Analysis of the characteristics of page owner
- GoLand 2021.1: rename the go project
- Solve the problem of dormitory router campus network sharing login
- Summary of common error reporting problems and positioning methods of thrift
- C language standard IO function sorting
- 战略、战术(和 OKR)
- Exercise 10-2 recursive factorial sum
- JVM family - overview, program counter day1-1
- Example analysis of QT learning 18 login dialog box
猜你喜欢

Exercise 10-6 recursively find Fabonacci sequence

Go: send the get request and parse the return JSON (go1.16.4)

Qt学习18 登录对话框实例分析

JS Part 2

Using registered classes to realize specific type matching function template

7-9 find a small ball with a balance

QT learning 17 dialog box and its types

Implementation of Muduo asynchronous logging

28:第三章:开发通行证服务:11:在配置文件中定义属性,然后在代码中去获取;

Current situation, analysis and prediction of information and innovation industry
随机推荐
QT learning 22 layout manager (I)
Redis: operation command of string type data
Why are grass-roots colleges and universities with "soil and poverty" called "Northeast small Tsinghua"?
Scroll detection of the navigation bar enables the navigation bar to slide and fix with no content
Installation impression notes
js . Find the first palindrome string in the array
Solve MySQL 1045 access denied for user 'root' @ 'localhost' (using password: yes)
“又土又穷”的草根高校,凭什么被称为“东北小清华”?
Webpage connection database ~ simple implementation of addition, deletion, modification and query complete code
Metal organic framework MOFs loaded with non steroidal anti-inflammatory drugs | zif-8 wrapped Prussian blue loaded quercetin (preparation method)
jvm-对象生命周期
Metal organic framework material zif-8 containing curcumin( [email protected] Nanoparticles) | nano metal organic framework carry
Dynamic programming 01 knapsack and complete knapsack
UiO-66-COOH装载苯达莫司汀|羟基磷灰石( HA) 包裹MIL-53(Fe)纳米粒子|装载黄芩苷锰基金属有机骨架材料
Function calling convention
Dlopen() implements dynamic loading of third-party libraries
JS new challenges
JS continues to explore...
7-9 find a small ball with a balance
MySQL data processing value addition, deletion and modification