1. 前言

grpc是一个高性能、开源的通用RPC框架,产自 Google,基于 ProtoBuf 序列化协议进行开发, 支持多种语言(Golang、Python、Java等),gRPC 对 HTTP/2 协议的支持使其在 Android、IOS 等客户端后端服务的 开发领域具有良好的前景。gRPC 提供了一种简单的方法来定义服务,同时客户端可以充分利用 HTTP/2 stream 的特性, 从而有助于节省带宽、降低 TCP 的连接次数、节省CPU的使用等。grpc详细可看grpc文档

2. 安装

要使用本项目的grpc列子,需要先安装以下软件和工具

2.1. gRPC 的安装

go get -u google.golang.org/grpc

2.2. protobuf的安装

下载:https://github.com/google/protobuf/releases
我的版本是:protoc-3.16.0-win32.rar
将解压出来的protoc.exe放在一全英文路径下,并把其路径名放在windows环境变量下的path下

2.3. 安装 golang protobuf

go get -u github.com/golang/protobuf/proto // golang protobuf 库
go get -u github.com/golang/protobuf/protoc-gen-go //protoc --go_out 工具

3. 编写proto文件

my-gin\proto\hello\hello.proto

syntax = "proto3"; // 指定proto版本
package hello;     // 指定默认包名

// 指定golang包名
option go_package = "my-gin/proto/hello";

// 定义Hello服务
service Hello {
    // 定义SayHello方法
    rpc SayHello(HelloRequest) returns (HelloResponse) {}
}

// HelloRequest 请求结构
message HelloRequest {
    string name = 1;
}

// HelloResponse 响应结构
message HelloResponse {
    string message = 1;
}

在go-gin\proto\hello目录下执行

protoc -I . --go_out=plugins=grpc:E:\www\my --proto_path . ./hello.proto

生成hello.pb.go文件,后续更改hello.proto内容,执行下上面的语句,就可更新hello.pb.go文件

4. grpc服务

my-gin\grpc\server.go文件下写grpc服务代码

package main

import (
    "fmt"
    "golang.org/x/net/context"
    "google.golang.org/grpc"
    "google.golang.org/grpc/reflection"
    pb "my-gin/proto/hello" // 引入编译生成的包
    "net"
)

const (
     // 这里使用的端口是写死的8081,你可尝试把端口写到配置里
    // Address gRPC服务地址
    Address = "127.0.0.1:8081"
)

// 定义helloService并实现约定的接口
type helloService struct{}

// HelloService Hello服务
var HelloService = helloService{}

// 开启grpc服务
func main() {
    listen, err := net.Listen("tcp", Address)
    if err != nil {
        fmt.Printf("Grpc Server Failed to listen: %v", err)
    }

    // 实例化grpc Server
    s := grpc.NewServer()

    // 注册HelloService
    pb.RegisterHelloServer(s, HelloService)

    // Register reflection service on gRPC server.
    reflection.Register(s)

    if err := s.Serve(listen); err != nil {
        fmt.Printf("failed  Server to serve: %v", err)
    }
}

// SayHello 实现Hello服务接口
func (h helloService) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloResponse, error) {
    resp := new(pb.HelloResponse)
    resp.Message = fmt.Sprintf("Hello %s.", in.Name)

    return resp, nil
}

5. 调用grpc

my-gin\routers\grpc.go

package routers

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "google.golang.org/grpc"
    pb "my-gin/proto/hello"
    "net/http"
)

// 数据解析常用
func GrpcRouter(e *gin.Engine) {

    // 使用路由组
    r := e.Group("/grpc")

    // http://127.0.0.1:8080/grpc/client?name=world
    r.GET("/client", client)
}


const ( 
     // 这里使用的端口是写死的8081,你可尝试把端口写到配置里
    // Address gRPC服务地址
    Address = "127.0.0.1:8081"
)

func client(c *gin.Context) {
    // 连接
    conn, err := grpc.Dial(Address, grpc.WithInsecure())
    if err != nil {
        fmt.Print(err)
    }
    defer conn.Close()

    // 初始化客户端
    client := pb.NewHelloClient(conn)

    name := c.DefaultQuery("name", "yzx-fjl.cn")

    // 调用方法
    req := &pb.HelloRequest{Name: name}
    res, err := client.SayHello(c, req)

    if err != nil {
        fmt.Print(err)
    }

    c.JSON(http.StatusOK, gin.H{"status": "200", "message": res})
}

http://127.0.0.1:8080/grpc/client?name=world
没开启服务时访问输出的是 :{"message":null,"status":"200"}
需要进入到my-gin\grpc 执行 go run server.go,开启grpc服务
页面上输出 {"message":{"message":"Hello world."},"status":"200"}这个就是成功的

Copyright © yzx该文章修订时间: 2021-09-09 18:46:27

results matching ""

    No results matching ""