# 安装spring核心包
go get -u github.com/go-spring/spring-core@v1.1.0-rc2
# 安装web starter
# gin
go get -u github.com/go-spring/starter-gin@v1.1.0-rc2
# 安装grpc starter
go get -u github.com/go-spring/starter-grpc@v1.1.0-rc2
# 安装grpc server
go get -u github.com/go-spring/starter-grpc/server@v1.1.0-rc2
# 安装grpc client
go get -u github.com/go-spring/starter-grpc/client@v1.1.0-rc2
|-- client
|-- main.go # 客户端启动文件
|-- server
|-- main.go # 服务端启动文件
|-- proto # 存放proto文件目录
|-- product.proto # 测试product grpc服务
|-- pb # 存放生成的go grpc pb文件
|-- product.pb.go # product service 生成的pb文件
|-- service # 服务实现
|-- product.go # product 服务实现
|-- go.mod
...
go 开发 grpc 相关配置及依赖参考 https://www.cnblogs.com/baoshu/p/13488106.html,主要安装一个protoc可执行文件与protoc-gen-go依赖来自动生成pb代码
在 proto目录下创建文件product.proto文件如下
syntax = "proto3";
// 定义go文件生成路径
option go_package = "proto/pb";
// 定义生成service的包名
package product;
// 定义服务
service Product {
// 定义rpc端点
rpc Produce (ProductRequest) returns(ProductResponse) {}
}
// 定义Produce端点的请求参数
message ProductRequest {
// 参数类型与参数名称
string name = 1;
int64 count = 2;
}
// 定义Produce端点的响应参数
message ProductResponse {
// 参数类型与参数名称
uint32 code = 1;
string msg = 2;
string items = 3;
}
在工程根目录下执行命令
# protoc我这里已经添加到环境变量了, 若为添加环境变量则需要写出protoc的全路径
protoc --go_out=plugins=grpc:./ ./proto/product.proto
在service目录下创建product.go文件
package service
import (
context "context"
// 引入生成的pb文件对应的模块
"xxx/proto/pb"
"strconv"
)
// 定义service 需要实现生成pb文件的ProductServer接口
type ProductService struct {
}
// pb.ProductServer接口实现
func (p *ProductService) Produce(ctx context.Context, request *pb.ProductRequest) (*pb.ProductResponse, error) {
return &pb.ProductResponse{
Code: 200,
Msg: "请求成功",
Items: "Produced " + strconv.FormatInt(request.Count, 10) + " product named \"" + request.Name + "\"",
}, nil
}
server/main.go
package main
import (
"github.com/go-spring/spring-base/log"
"github.com/go-spring/spring-core/grpc"
"github.com/go-spring/spring-core/gs"
// 引入grpc server starter
_ "github.com/go-spring/starter-grpc/server"
"xxx/proto/pb"
"xxx/service"
)
func init() {
// 创建service.ProductService bean示例并设置初始方法
gs.Object(new(service.ProductService)).Init(func(srv *service.ProductService) {
// 添加grpc服务
// gs.GrpcServer(string, *grpc.Server) 其中第一个参数为serviceName, 要求与生成的pb文件Service.Desc中的ServiceName参数值相等
gs.GrpcServer("product.Product", &grpc.Server{
// 服务注册方法
Register: pb.RegisterProductServer,
// 服务实现对象
Service: srv,
})
})
}
func main() {
// 设置grpc访问端口
gs.Property("grpc.server.port", 8081)
log.Fatal(gs.Run())
}
client/main.go
package main
import (
"github.com/go-spring/spring-core/gs"
"github.com/go-spring/spring-core/web"
// 引入gin web starter, 若不需要提供web访问可以移除该依赖
_ "github.com/go-spring/starter-gin"
// 引入 grpc client starter
_ "github.com/go-spring/starter-grpc/client"
"xxx/proto/pb"
"log"
)
func init() {
// 配置product访问端点, 配置结构为 grpc.endpoint.xxx.address 其中xxx为自己定义的名称
gs.Property("grpc.endpoint.product.address", "127.0.0.1:8081")
// 1.gs.GrpcClient(interface{}, string)创建grpc客户端bean实例, 第二个参数的endpoint名称必须与上面引入的名称一致
// 2.Init(..) bean初始化的方法
gs.GrpcClient(pb.NewProductClient, "product").Init(func(client pb.ProductClient) {
// 创建Web端点
gs.GetMapping("/", func(ctx web.Context) {
// 调用rpc服务端实现并获取结果
products, err := client.Produce(ctx.Context(), &pb.ProductRequest{
Name: ctx.QueryParam("name"),
Count: 10,
})
// 结果返回
if err != nil {
ctx.JSON(web.ERROR.Error(err))
} else {
ctx.JSON(products)
}
})
})
}
func main() {
log.Fatal(gs.Run())
}