热门标签 | 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 ... [详细]
  • 按照之前我对map的理解,map中的数据应该是有序二叉树的存储顺序,正常的遍历也应该是有序的遍历和输出,但实际试了一下,却发现并非如此,网上查了下,发现从Go1开始,遍历的起始节点就是随机了,当然随机 ... [详细]
  • 看到平台银行对接方案写的demo确实还不错记个笔记互相学习学习packageapiimport(cryptotlsnetnethttpstringssynct ... [详细]
  • 本文介绍了在Android项目中实现时间轴效果的方法,通过自定义ListView的Item布局和适配器逻辑,实现了动态显示和隐藏时间标签的功能。文中详细描述了布局文件、适配器代码以及时间格式化工具类的具体实现。 ... [详细]
  • Android商城应用开发指南(第二部分):创建启动欢迎页
    大多数商城应用程序在启动时会显示一个欢迎页面,以提升用户体验。本文将指导您如何实现一个基本的欢迎页,该页面会在用户打开应用后短暂展示,随后自动跳转至主界面。 ... [详细]
  • 目录在Go语言项目中使用Zap日志库介绍默认的GoLogger日志库实现GoLogger设置Logger使用LoggerLogger的运行GoLogger的优势和劣势优势劣势Ube ... [详细]
  • EasyMock实战指南
    本文介绍了如何使用EasyMock进行单元测试,特别是当测试对象的合作者依赖于外部资源或尚未实现时。通过具体的示例,展示了EasyMock在模拟对象行为方面的强大功能。 ... [详细]
  • 本文探讨了Web开发与游戏开发之间的主要区别,旨在帮助开发者更好地理解两种开发领域的特性和需求。文章基于作者的实际经验和网络资料整理而成。 ... [详细]
  • Go语言开发中的常见陷阱与解决方案
    本文探讨了在使用Go语言开发过程中遇到的一些典型问题,包括Map遍历的不确定性、切片操作的潜在风险以及并发处理时的常见错误。通过具体案例分析,提供有效的解决策略。 ... [详细]
  • 1Authenticator简介1.1层次结构图1.2作用职责是验证用户帐号,是ShiroAPI中身份验证核心的入口点;接口中声明的authenticate方法就是用来实现认证逻辑 ... [详细]
  • 本文csdn博客链接:http:blog.csdn.netscrescentarticledetails51135307本文qq空间链接:http:user.qzone.qq.com ... [详细]
  • 使用gin改写“SectionBuildingRESTfulAPIs”第三方包需要提前准备的包有:“gopkg.ingin-gonicgin.v1”“gopkg.inmgo.v2” ... [详细]
  • 认真一点学 Go:18. 并发
    收录于《Go基础系列》,作者:潇洒哥老苗。>>原文链接学到什么并发与并行的区别?什么是Goroutine?什么是通道?Goroutine如何通信?相关函数的使用?sel ... [详细]
  • Go冒泡排序练习
    package main要求:随机生成5个元素的数组,并使用冒泡排序对其排序  从小到大思路分析:随机数用mathrand生成为了更好 ... [详细]
  • Go 快速入门指南命令行参数
    命令行参数个数调用os包即可。获取参数个数,遍历参数packagemainimport(fmtos)funcmain(){fmt.Printf(Numberofargsi ... [详细]
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社区 版权所有