Golang之gRPC初识

Posted 钉大爷

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang之gRPC初识相关的知识,希望对你有一定的参考价值。

什么是gRPC

gRPC是谷歌基于http/2设计标准设计,并使用谷歌自身设计的ProtoBuf(Protocol Buffers)系列化协议开发的一套支持各种端的感觉超牛逼的一个RPC协议。

gRPC的支持

gRPC支持多种语言,并且能够基于语言本身生成客户端跟服务端库。目前在gayhub上,不对github上已经有几个语言版本支持:C版本的grpc、Java版本的grpc-java、Go版本的grpc-go。其他的还正在开发中,其中 grpc 支持 C、C++、Node.js、Python、Ruby、Objective-C、php和C#等语言,grpc-java 已经支持 android 开发。

gRPC相对于其他RPC的好处

简化、高性能、节能等等,这里就不细说了。

Go项目如何使用gRPC

初始环境搭建

安装 protoc 执行文件

Mac系统

> brew install protobuf

Centos 7系统

> yum install protobuf

或者可以直接访问该网站去下载编译好的可执行文件 https://github.com/google/protobuf/releases

安装gRPC

> go get -u google.golang.org/grpc  //将grpc源码下载到本地并进行编译安装
> go get -u github.com/golang/protobuf/protoc-gen-go    //下载golang版本的protoc插件
> export PATH=$PATH:$GOPATH/bin  //将golang的GOPATH/bin环境配置成到路径环境变量中去

现在基本环境都搭建好了,我们可以下载官方的示例项目https://github.com/grpc/grpc-go或者可以用我简单的gRPC项目https://github.com/jerbe/samplegrpc。

生成proto 的go 版本源码

这里开始,我用我的项目代码为例。 我们先在项目中建立一个 im.proto 文件,这个文件是可以通过 protoc 解析生成一个golang源码文件

syntax = "proto3";   //语言版本,默认是proto2,我们使用proto3,比较牛逼

package im;   //这里是生成的文件包名

service IM {  //服务名称
  rpc Sample(Request) returns (Response){}   //客户端单次请求,服务端单次返回
  rpc ResponseStream(Request) returns (stream Response){}  //客户端单次请求,服务端流式返回
  rpc RequestStream(stream Request) returns (Response){}   //客户端流式请求,服务端单次返回
  rpc BilateralStream(stream Request) returns (stream Response){}   //客户端流式请求,服务端流式返回
}

message Request {   //请求对象
  string message = 1;           //请求对象的一系列参数
}

message Response {      //返回对象
  string message = 1;       //返回对象的一系列参数
}

现在,我们将这个文件进行解析生成golang源码文件

//在项目根路径执行
> protoc -I./proto/im --go_out=plugins=grpc:./proto/im im.proto 
//也可以进入到  ./proto/im 目录执行
> protoc --go_out=plugins=grpc:. im.proto 

这样在./proto/im文件夹里面就会出现一个 im.pb.go的文件了,里面就是解析生成的源码文件,这里我们就不展开了。

服务端主要源码

服务端的主要的任务就是接收客户端发送的数据,并相应不同方式的数据。
代码主要是注册一个通过protoc生成一个接口Server对象,Server对象的方法都必须在im.pb.go 里面的 IMServer 接口中有。

im.pb.go 的IMServer 接口结构

// IMServer is the server API for IM service.
type IMServer interface {
    Sample(context.Context, *Request) (*Response, error)
    ResponseStream(*Request, IM_ResponseStreamServer) error
    RequestStream(IM_RequestStreamServer) error
    BilateralStream(IM_BilateralStreamServer) error
}

main.go 的主要内容

type Server struct{
}
func (s *Server) Sample(ctx context.Context, request *im.Request) (response *im.Response, err error){
...
}

func (s *Server) ResponseStream(request *im.Request, responseServer im.IM_ResponseStreamServer) error{
...
}

func (s *Server) RequestStream(requestServer im.IM_RequestStreamServer) error{
...
}

func (s *Server) BilateralStream(bilateralServer im.IM_BilateralStreamServer) error{
...
}

func main(){
listen,err := net.Listen("tcp",ListenAddress)       //开启一个端口监听
    if err != nil {
        fmt.Println(err.Error())
    }

    grpcServer := grpc.NewServer()     //生成一个grpc服务
    im.RegisterIMServer(grpcServer,&Server{})    //
    err = grpcServer.Serve(listen)
    if err != nil {
        fmt.Println("error:",err.Error())
    }
}   

客户端主要源码

客户端主要的任务就是发送数据到服务端,并接收不同方式返回的数据。

func main(){
    conn,err := grpc.Dial(ListenAddress)  //与服务器进行拨号连接
    if err != nil {
        fmt.Println(err.Error())
        os.Exit(1)
    }

    defer func() {
        err := conn.Close()
        if err != nil {
            fmt.Println(err.Error())
            os.Exit(1)
        }
    }()
    client := im.NewIMClient(conn)   //初始化一个客户端对象
    ...
    剩下的就是使用client做对应的事情了。
}

代码主要使用方式

主要就是对方法里面的各个参数调用,比如Servcer的recv必须使用for,因为它是一个流式传输,并且recv的时候必须判断error是否为io.EOF,就是说客户端没有数据再返回了。具体使用方法还是clone代码下来看吧。有点晚了,该睡觉了。


以上是关于Golang之gRPC初识的主要内容,如果未能解决你的问题,请参考以下文章

Golang RPC 之 gRPC

grpc之golang学习笔记2

grpc应用之二 gRPC使用

gRPC之双向认证初入

如何安装golang的grpc插件

Golang gRPC 示例