热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

protobuf3教程

本文主要分享【protobuf3教程】,技术文章【4、protobuf进阶】为【无休止符】投稿,如果你遇到Go微服务实战-电商系统相关问题,本文相关知识或能到你。protobuf3教程目

本文主要分享【protobuf 3教程】,技术文章【4、protobuf进阶】为【无休止符】投稿,如果你遇到Go微服务实战-电商系统相关问题,本文相关知识或能到你。

protobuf 3教程

目录 一、proto的类型二、option go_package三、proto文件import另外一个文件的message四、message嵌套五、enum使用六、map使用七、proto的内置timestamp

protobuf官方文档参考:http://developers.google.com/protocol-buffers/docs/proto3
一、proto的类型 proto的默认数值类型:当一个消息被解析的时候,如果被编码的信息不包含一个特定的singular元素,被解析的对象锁对应的域被设置为一个默认值,对于不同类型指定如下 对于strings,默认值是一个空string对于bytes,默认值是一个空的bytes对于bools,默认值是false对于数值类型,默认是0对于枚举,默认是第一个定义的枚举值,必须为0

protobuf 3教程


protobuf 3教程


二、option go_package

我们之前在stream.proto中配置的包路径为option go_package = ".;proto";,这时候生成的proto文件路径是跟stream.proto同级目录下

对应的生成命令是: protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative *.proto

protobuf 3教程

这时候思考,如果我们希望将pb.go生成到其他路径

修改option go_package配置: option go_package = "common/stream/proto/v1";生成命令:注意这时候不应该再使用source_relative,而应该使用import,如 protoc --go_out=. --go_opt=paths=import --go-grpc_out=. --go-grpc_opt=paths=import *.proto

protobuf 3教程

如果我们希望生成到根目录的其他路径

修改option go_package配置: option go_package = "../../common/stream/proto/v1";生成命令:注意这时候不应该再使用source_relative,而应该使用import,如 protoc --go_out=. --go_opt=paths=import --go-grpc_out=. --go-grpc_opt=paths=import *.proto

protobuf 3教程


三、proto文件import另外一个文件的message hello.proto
syntax = "proto3";
import "base.proto";
option go_package = ".;proto";

service Greeter {
   
  rpc SayHello (HelloRequest) returns (HelloReply);
  rpc Ping(Empty) returns (Pong);
}

message HelloRequest {
   
  string name = 1;
}

message HelloReply {
   
  string message = 1;
}
base.proto:比较公用的message
syntax = "proto3";

message Empty{
   

}

message Pong{
   

}
实际上谷歌已经自定义了Empty:而且还包含很多其他的内置message

protobuf 3教程

修改后的proto:注意需要在golang中修改导入的位置,如图
//hello.proto
syntax = "proto3";
import "base.proto";
import "google/protobuf/empty.proto";
option go_package = ".;proto";

service Greeter {
   
  rpc SayHello (HelloRequest) returns (HelloReply);
  rpc Ping(google.protobuf.Empty) returns (Pong);
}

message HelloRequest {
   
  string name = 1;
}

message HelloReply {
   
  string message = 1;
}

//base.proto
syntax = "proto3";

message Pong{
   

}

protobuf 3教程


四、message嵌套 message嵌套
message HelloReply {
   
    string message = 1;

    message Result {
   
        string name = 1;
        string url = 2;
    }

    repeated Result data = 2;
}
嵌套后生成的pb.go代码是HelloReply_Result
type HelloReply_Result struct {
   
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	Url  string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
}

五、enum使用 hello.proto
message HelloRequest {
   
  string name = 1;
  string url = 2;
  Gender g = 3;
}

enum Gender{
   
  MALE = 0;
  FEMALE = 1;
}
hello.pb.go
type Gender int32

const (
	Gender_MALE   Gender = 0
	Gender_FEMALE Gender = 1
)
client.go
	c := proto.NewGreeterClient(conn)
	r, err := c.SayHello(context.Background(), &proto.HelloRequest{
   
		Name: "test",
		Url:  "hel.com",
		G:    proto.Gender_FEMALE,
	})

六、map使用 hello.proto
message HelloRequest {
   
  string name = 1;
  string url = 2;
  Gender g = 3;
  map<string, string> mp = 4;
}
hello.pb.go
type HelloRequest struct {
   
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Name string            `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	Url  string            `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
	G    Gender            `protobuf:"varint,3,opt,name=g,proto3,enum=Gender" json:"g,omitempty"`
	Mp   map[string]string `protobuf:"bytes,4,rep,name=mp,proto3" json:"mp,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
client.go
	c := proto.NewGreeterClient(conn)
	r, err := c.SayHello(context.Background(), &proto.HelloRequest{
   
		Name: "test",
		Url:  "hel.com",
		G:    proto.Gender_FEMALE,
		Mp: map[string]string{
   
			"name":    "test",
			"company": "my",
		},
	})

七、proto的内置timestamp timestamp的importimport "google/protobuf/timestamp.proto"; hello.proto的定义:内置类型都需要 google.protobuf开头
syntax = "proto3";
import "base.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";
option go_package = ".;proto";

service Greeter {
   
  rpc SayHello (HelloRequest) returns (HelloReply);
  rpc Ping(google.protobuf.Empty) returns (Pong);
}

message HelloRequest {
   
  string name = 1;
  string url = 2;
  Gender g = 3;
  map<string, string> mp = 4;
  google.protobuf.Timestamp addTime = 5;
}

enum Gender{
   
  MALE = 0;
  FEMALE = 1;
}

message HelloReply {
   
  string message = 1;

  message Result {
   
    string name = 1;
    string url = 2;
  }

  repeated Result data = 2;
}
hello.pb.go:可以看到AddTime的类型是 *timestamppb.Timestamp,点击后查看import就是client.go需要import的包名 timestamppb "google.golang.org/protobuf/types/known/timestamppb"
type HelloRequest struct {
   
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Name    string                 `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	Url     string                 `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
	G       Gender                 `protobuf:"varint,3,opt,name=g,proto3,enum=Gender" json:"g,omitempty"`
	Mp      map[string]string      `protobuf:"bytes,4,rep,name=mp,proto3" json:"mp,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
	AddTime *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=addTime,proto3" json:"addTime,omitempty"`
}
client.go
package main

import (
	"context"
	"fmt"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"google.golang.org/protobuf/types/known/timestamppb"
	"time"

	"MyTestProject/grpc_test/proto"
)

func main() {
   
	//stream
	conn, err := grpc.Dial("127.0.0.1:50051", grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
   
		fmt.Println(err.Error())
		return
	}
	defer conn.Close()

	c := proto.NewGreeterClient(conn)
	r, err := c.SayHello(context.Background(), &proto.HelloRequest{
   
		Name: "test",
		Url:  "hel.com",
		G:    proto.Gender_FEMALE,
		Mp: map[string]string{
   
			"name":    "test",
			"company": "my",
		},
		AddTime: timestamppb.New(time.Now()),
	})
	if err != nil {
   
		fmt.Println(err.Error())
		return
	}
	fmt.Println(r.Message)
}


本文《4、protobuf进阶》版权归无休止符所有,引用4、protobuf进阶需遵循CC 4.0 BY-SA版权协议。


推荐阅读
  • golang 解析磁力链为 torrent 相关的信息
    其实通过http请求已经获得了种子的信息了,但是传播存储种子好像是违法的,所以就存储些描述信息吧。之前python跑的太慢了。这个go并发不知道写的有没有问题?!packag ... [详细]
  • 0.编写.proto文件:syntaxproto3;optionjava_multiple_filestrue;optionjava_packageio.grp ... [详细]
  • 本文介绍了解决Netty拆包粘包问题的一种方法——使用特殊结束符。在通讯过程中,客户端和服务器协商定义一个特殊的分隔符号,只要没有发送分隔符号,就代表一条数据没有结束。文章还提供了服务端的示例代码。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • 本文详细介绍了使用C#实现Word模版打印的方案。包括添加COM引用、新建Word操作类、开启Word进程、加载模版文件等步骤。通过该方案可以实现C#对Word文档的打印功能。 ... [详细]
  • 流数据流和IO流的使用及应用
    本文介绍了流数据流和IO流的基本概念和用法,包括输入流、输出流、字节流、字符流、缓冲区等。同时还介绍了异常处理和常用的流类,如FileReader、FileWriter、FileInputStream、FileOutputStream、OutputStreamWriter、InputStreamReader、BufferedReader、BufferedWriter等。此外,还介绍了系统流和标准流的使用。 ... [详细]
  • zuul 路由不生效_Zuul网关到底有何牛逼之处?竟然这么多人在用~
    作者:kosamino来源:cnblogs.comjing99p11696192.html哈喽,各位新来的小伙伴们,大家好& ... [详细]
  • 千万不要错过的后端[纯干货]面试知识点整理 I I
    千万不要错过的后端【纯干货】面试知识点整理IIc++内存管理上次分享整理的面试知识点I,今天我们来继续分享面试知识点整理IIlinuxkernel内核空间、内存管理、进程管理设备、 ... [详细]
  • golang反射,golang反射性能
    本文目录一览:1、关于反射2、尝试用golan ... [详细]
  • 本文介绍了在Python中使用gRPC的方法示例,分享给大家,具体如下:使用ProtocolBuffers的跨平台RPC系统。安装使用pi ... [详细]
author-avatar
mobiledu2502929493
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有