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"}这个就是成功的