gPRC
protobuf基本操作
前置
安装gRPC,使用
go get google.golang.org/grpc
来获取包。安装protoc来进行编译,使用
go get github.com/golang/protobuf/protoc-gen-go
来获取包。
proto文件编写
Protocol Buffers
常用概念
- Message 定义: 描述了一个请求或者响应的消息格式。
singular
:成员有\(0\)个或者\(1\)个,一般是省略不写。repeated
:表示该字段包括了\(0 \sim n\)个元素。- 字段标识: 消息定义中,每个字段都有一个唯一的数值标签。
- 常用数据类型:
double
,float
,int32
,int64
,bool
,string
,bytes
。 Service
服务定义: 在Service中可以定义RPC
服务接口。
proto文件
//指定当前语法版本 (默认为proto2)
syntax = "proto3";
//option go_package = "path;name"; path -> 地址 name -> 所属包名
option go_package = "../pb_gen";
//指定生成文件的package
package pb;
//消息 传输的对象 定义传输的数据格式 类似于struct
/**
默认为必填字段 也就是proto2里面的required -> 1
标识号必须填写且唯一 -> 2
optional 可选字段 -> 3
repeated 可重复字段 go里面重复会被定义为切片 -> 4
*/
message Person{
string name = 1;
int32 age = 2;
}
service hello{
rpc SayHello(Person) returns (Person);
}
proto文件编译
编写好proto文件后使用
protoc --go_out=plugins=grpc:./ *.proto
来进行编译。
生成的go文件(源文件很长,没有完全展示)
//进行rpc封装
type HelloClient interface {
SayHello(ctx context.Context, in *Person, opts ...grpc.CallOption) (*Person, error)
}
//客户端封装
type helloClient struct {
cc grpc.ClientConnInterface
}
// 初始化grpc客户端
func NewHelloClient(cc grpc.ClientConnInterface) HelloClient {
return &helloClient{cc}
}
//远程函数
func (c *helloClient) SayHello(ctx context.Context, in *Person, opts ...grpc.CallOption) (*Person, error) {
out := new(Person)
err := c.cc.Invoke(ctx, "/pb.hello/SayHello", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// 服务端封装
type HelloServer interface {
SayHello(context.Context, *Person) (*Person, error)
}
//服务注册
func RegisterHelloServer(s *grpc.Server, srv HelloServer) {
s.RegisterService(&_Hello_serviceDesc, srv)
}
gRPC演示
服务端
常规步骤
1. 初始化gRPC对象
2. 注册服务
3. 设置监听
4. 启动服务
服务端代码
package main
import (
"context"
"fmt"
"go-consul/demo/pb_gen"
"google.golang.org/grpc"
"net"
)
// 2.2定义类
type Person struct {
}
// 2.3绑定方法
func (Person) SayHello(ctx context.Context, person *pb_gen.Person) (*pb_gen.Person, error) {
person.Name += "hello"
return person, nil
}
func main() {
//1 初始化对象
server := grpc.NewServer()
//2.1注册服务
pb_gen.RegisterHelloServer(server, new(Person))
//3.设置监听,指定ip和port
listen, err := net.Listen("tcp", ":8080")
if err != nil {
fmt.Println("监听出错")
return
}
//4.启动服务
err = server.Serve(listen)
if err != nil {
fmt.Println("启动服务失败")
return
}
}
客户端
常规步骤
1. 连接服务
2. 初始化gPRC客户端
3. 调用远程函数
客户端代码
package main
import (
"context"
"fmt"
"go-consul/demo/pb_gen"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
func main() {
//1.连接服务
//grpc.WithInsecure() 已被弃用 使用如下代替
dial, err := grpc.Dial(":8080", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
fmt.Println("连接失败")
return
}
//2.初始化grpc客户端
client := pb_gen.NewHelloClient(dial)
//3.调用远程函数
var person pb_gen.Person
person.Name = "jxc"
person.Age = 20
p, err := client.SayHello(context.TODO(), &person)
if err != nil {
fmt.Println("调用失败")
return
}
fmt.Println(p)
}