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)
}

gRPC + consul 的一个小demo

gRPC + Consul