更方便的在微信公众号阅读文章可以关注公众号:海生的go花园
一、介绍
在第五章,我们学习了.pb.go文件
《go入门grpc》第五章:protoc生成的.pb.go文件解读
本章我们学习下protoc --go-grpc_out
命令生成的_grpc.pb.go文件。
我们以hello.proto文件为例,代码如下:
syntax = "proto3";
package hello;
import "google/protobuf/timestamp.proto";
option go_package = "github/hisheng/grpc-demo1/api";
service Say {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
google.protobuf.Timestamp last_updated = 2;
}
使用protoc --go-grpc_out
命令生成了 hello_grpc.pb.go文件。
package api
......
type SayClient interface {
SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error)
}
......
type SayServer interface {
SayHello(context.Context, *HelloRequest) (*HelloReply, error)
mustEmbedUnimplementedSayServer()
}
......
主要有三部分
- package
- Server服务端接口
- Client客户端接口
二、Server服务端接口
_grpc.pb.go自动生成的文件,提供了一个注册服务的方法RegisterSayServer
我们写微服务server端,是启动一个grpc服务器,然后通过RegisterSayServer方法,把 各种服务注册进去。
// SayServer 是 Say service提供api的接口
// 所有的自定义service,都必须把UnimplementedSayServer嵌入
// 才能调用SayServer接口
type SayServer interface {
SayHello(context.Context, *HelloRequest) (*HelloReply, error)
mustEmbedUnimplementedSayServer()
}
// UnimplementedSayServer 最原始的SayServer接口实现。
type UnimplementedSayServer struct {
}
func (UnimplementedSayServer) SayHello(context.Context, *HelloRequest) (*HelloReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented")
}
func (UnimplementedSayServer) mustEmbedUnimplementedSayServer() {}
func RegisterSayServer(s grpc.ServiceRegistrar, srv SayServer) {
s.RegisterService(&Say_ServiceDesc, srv)
}
server 端提高了 UnimplementedSayServer,我们自己实现,这个相当于是基类。需要内嵌到我们的结构体中。
server 定义了一个对外可以使用api接口的接口SayServer
然后再生成了一个 最底层实现UnimplementedSayServer,供我们自己实现的时候,嵌入进去,然后重写其方法。
思考:
为什么要 UnimplementedSayServer ?
因为go里面,没有继承这一个 原语,我们通过嵌入的方式,实现类似的效果。
如果没有UnimplementedSayServer,那么其他的地方也写了一个 SayHello方法,但它加入是供http调用的,那么它算不算 实现了SayServer接口呢?
通过加 UnimplementedSayServer,我们知道了,它是grpc,没加就不算grpc,就很一目了然。
三、Client客户端接口
SayClient 是 SayService 的 客户端。
主要包括定义了一个SayClient接口,以及一个sayClient结构体。
sayClient结构体实现了SayClient接口。
对外提供一个 NewSayClient()来生成初始化SayClient客户端。
type SayClient interface {
SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error)
}
type sayClient struct {
cc grpc.ClientConnInterface
}
func NewSayClient(cc grpc.ClientConnInterface) SayClient {
return &sayClient{cc}
}
func (c *sayClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) {
out := new(HelloReply)
err := c.cc.Invoke(ctx, "/hello.Say/SayHello", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。