2

更方便的在微信公众号阅读文章可以关注公众号:海生的go花园
图片

一、介绍

经过前面的基础知识的讲解,我们了解到了 protoc 命令的作用,帮我们自动化生成
go代码。主要有.pb.go 以及_grpc.pb.go 文件。
目前的代码我放到了github上,可以查看完整的代码。
https://github.com/hisheng/grpc-demo1
我们再复习一下当前的目录结构如下:

➜  grpc-demo1 git:(master) ✗ tree
.
├── Makefile
├── api
│   ├── hello.pb.go
│   ├── hello.proto
│   ├── hello_grpc.pb.go
│   ├── user.pb.go
│   └── user.proto
├── go.mod
└── go.sum

1 directory, 8 files

我们实现一个grpc服务器主要有两个步骤

  1. 使用官方的grpc.NewServer(),新建 grpc服务器
  2. 实现 _grpc.pb.go 里面的 server接口,并且register到 grpc服务器中

二、新建grpc服务器

我们使用官方的grpc包,来新建一个 grpc服务器。
官方库google.golang.org/grpc,提供了一个 grpc.NewServer()方法。
新建一个grpc服务器主要有5步。

  1. 监听端口号 net.Listen()
  2. 新建grpc服务器 grpc.NewServer()
  3. 注册自己的方法到grpc服务器
  4. 启用grpc服务器 (s *Server) Serve(lis net.Listener)
  5. 优雅关闭 grpc server

我们在api同级新建一个server目录,同时新建一个main.go如下

➜  grpc-demo1 git:(master) tree
.
├── Makefile
├── api
│   ├── hello.pb.go
│   ├── hello.proto
│   ├── hello_grpc.pb.go
│   ├── user.pb.go
│   └── user.proto
├── go.mod
├── go.sum
└── server
    └── main.go

2 directories, 9 files
➜  grpc-demo1 git:(master) ✗ 

server目录下的main.go代码如下:

package main

import (
    "google.golang.org/grpc"
    "log"
    "net"
    "os"
    "os/signal"
)

func main() {
    // 1.8083 作为grpc的监听端口号
    lis, err := net.Listen("tcp", ":8083")
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    // 2. 新建一个 grpc server
    server := grpc.NewServer()
    // 3 . 注册自己的方法 到 grpc服务器中
    // todo 使用 _grpc.pb.go 里面的register方法

    // 4. 启动 grpc server
    if err := server.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }

    // 5.关闭 grpc server
    quit := make(chan os.Signal, 1)
    signal.Notify(quit, os.Interrupt)
    <-quit
    log.Println("stopping gRPC server...")
    server.GracefulStop()
}

三、实现 _grpc.pb.go里面的server接口,并且register到grpc服务器中

使用grpc的好处是自动生成的_grpc.pb.go文件已经告诉我们怎么做了。
就是两步:

  1. 新建一个自己的struct,内嵌UnimplementedSayServer (每个文件都有一个自己的,名字不一样)
  2. 实现server的接口方法

3.1 实现_grpc.pb.go里面的server接口

我们在server的目录下,建一个hello.go代码如下:

package main

import (
    "context"
    "fmt"
    "github/hisheng/grpc-demo1/api"
)

type hello struct {
    api.UnimplementedSayServer
}

func (h hello) SayHello(ctx context.Context, req *api.HelloRequest) (*api.HelloReply, error) {
    mes := fmt.Sprintf("来自grpc server SayHello %s", req.Name)
    return &api.HelloReply{Message: mes}, nil
}

这里,就是我们自己,实现的SayHello逻辑,接受HelloRequest参数,然后返回HelloReply

3.2 注入到 grpc服务器中。

每一个_grpc.pb.go都有一个注册方法,供我们调用,把自己实现的方法,注册到grpc服务器中。
在我们的hello_grpc.pb.go文件中自动生成的方法是:

func RegisterSayServer(s grpc.ServiceRegistrar, srv SayServer) {
    s.RegisterService(&Say_ServiceDesc, srv)
}

参数是grpc.ServiceRegistrar接口,在我们这里就是grpc.NewServer()
我们打开server目录下的main.go,注册下:

    // 3 . 注册自己的方法 到 grpc服务器中
    // todo 使用 _grpc.pb.go 里面的register方法
    api.RegisterSayServer(server, hello{})

在第三步骤下,增加这个RegisterSayServer方法。
注册完,完成的 main.go代码如下:

package main

import (
    "github/hisheng/grpc-demo1/api"
    "google.golang.org/grpc"
    "log"
    "net"
    "os"
    "os/signal"
)

func main() {
    // 1.8083 作为grpc的监听端口号
    lis, err := net.Listen("tcp", ":8083")
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    // 2. 新建一个 grpc server
    server := grpc.NewServer()
    // 3 . 注册自己的方法 到 grpc服务器中
    // todo 使用 _grpc.pb.go 里面的register方法
    api.RegisterSayServer(server, hello{})

    // 4. 启动 grpc server
    if err := server.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }

    // 5.关闭 grpc server
    quit := make(chan os.Signal, 1)
    signal.Notify(quit, os.Interrupt)
    <-quit
    log.Println("stopping gRPC server...")
    server.GracefulStop()
}

3.3 启动

我们在项目目录执行 go run,就启动了一个监听 8083端口的grpc服务器

grpc-demo1 git:(master) ✗ go run ./server

四、请求一下grpc服务器

我们这里使用BloomRPC这个可视化的grpc请求工具来,请求下。
具体这个工具怎么样,请看我的其他文章。
成功的返回了。
image.png


海生
104 声望32 粉丝

与黑夜里,追求那一抹萤火。