文章目录
- protobuf 和 grpc 的区别
- 下载工具 protoc
- 为什么要使用 protoc
- protoc 基本语法
- 基础用法
- 结构体声明
- protoc生成结构体
- 服务声明
- 生成服务
- 使用生成的服务端
- 使用生成的客户端
protobuf 和 grpc 的区别
grpc 是开源的rpc框架
protobuf是编码协议
下载工具 protoc
https://github.com/protocolbuffers/protobuf/releases
从上面选择匹配的版本,我暂时使用的windows64
下载解压后,将可执行文件 protoc.exe 加入环境变量中去
protoc --version 查看是否配置完成
为什么要使用 protoc
protoc + protoc-gen-go 能根据 .proto 文件生成go的代码,我们只要关心业务逻辑的实现即可
protoc-gen-go 通过 go get github.com/golang/protobuf/protoc-gen-go 安装
protoc 基本语法
基础用法
固定版本语法写法,现在使用proto3
go_package 指定生成的文件存储位置和文件package名称,注意文件存储位置必须包含"/"
//固定版本语法写法,现在使用proto3
syntax="proto3";
//go_package 指定生成的文件存储位置和文件package名称,注意文件存储位置必须包含"/"
option go_package = "./;demopb";
结构体声明
结构体声明使用message,message中变量类型写在前面,名称在后面。 = number 代表参数接受顺序(是按照顺序赋值)
//结构体声明使用message,message中变量类型写在前面,名称在后面。 = number 代表参数接受顺序(是按照顺序赋值)
message DemoRequest {
string name = 1;
int64 age = 2;
}
message DemoResponse{
string data = 1;
}
protoc生成结构体
-I 输入位置 --go_out=:输出位置
# -I 输入位置 --go_out=:输出位置
# 将当前目录下的demo.proto 生成代码放在 当前目录下
protoc -I . stream.proto --go_out=:.
服务声明
服务使用 service 声明,其中方法以rpc标记,入参和出参为message定义的结构体
service Demo {
rpc Talk(DemoRequest) returns (DemoResponse);
}
生成服务
# 将当前目录下demo.protoc 生成结构体和grpc服务
protoc -I . stream.proto --go_out=plugins=grpc:.
使用生成的服务端
使用前确保已经有grpc,没有通过 go get google.golang.org/grpc 安装
grpc.NewServer 创建grpc服务者
向服务者中注册服务,注册方法已经由protoc生成好了。方法名=Register + proto中rpc声明的方法名称 + server,将实现服务的struct传入即可(duck typing)
通过服务者的Serve(conn) 启动服务
package main
import (
demopb "Study/Three/Pro"
"context"
"fmt"
"google.golang.org/grpc"
"net"
)
type DemoServer struct {
}
func (s DemoServer) Talk(ctx context.Context, request *demopb.DemoRequest) (*demopb.DemoResponse, error) {
return &demopb.DemoResponse{
Data: fmt.Sprintf("我叫%s,今年%d岁", request.Name, request.Age),
}, nil
}
func main() {
//grpc.NewServer 创建grpc服务者
server := grpc.NewServer()
//向服务者中注册服务,注册方法已经由protoc生成好了。方法名=Register + proto中rpc声明的方法名称 + server,将实现服务的struct传入即可(duck typing)
demopb.RegisterDemoServer(server, &DemoServer{})
listen, _ := net.Listen("tcp", ":8083")
//通过服务者的Serve(conn) 启动服务
server.Serve(listen)
}
使用生成的客户端
通过grpc.Dial拨号得到conn
调用 protoc生成的创建客户端方法(方法名 = New + proto中声明的rpc方法名 + Client)
调用客户端的方法,传入指定的类型的入参,获取返回的结果
package main
import (
demopb "Study/Three/Pro"
"context"
"fmt"
"google.golang.org/grpc"
)
func main() {
//通过grpc.Dial拨号得到conn
dial, _ := grpc.Dial(":8083", grpc.WithInsecure())
//调用 protoc生成的创建客户端方法(方法名 = New + proto中声明的rpc方法名 + Client)
client := demopb.NewDemoClient(dial)
//调用客户端的方法,传入指定的类型的入参,获取返回的结果
talk, _ := client.Talk(context.Background(), &demopb.DemoRequest{
Name: "kiki",
Age: 18,
})
fmt.Println(talk.Data)
}