一. 环境准备。
- 创建一个
consul
服务中间件。 - 安装
protocol buffers
。
二. 编译proto文件。
- 创建需要的
proto
文件。
Model.proto文件
syntax = "proto3";
package Services;
message ProdModel{
int32 ProdID=1;
string ProdName=2;
}
ProdService.proto文件
syntax = "proto3";
package Services;
import "Models.proto";
message ProdsRequest{
int32 size=1;
}
message ProdListResponse{
repeated ProdModel Data=1;
}
service ProdService {
rpc GetProdsList(ProdsRequest) returns(ProdListResponse);
}
- 进行编译。
protoc --micro_out=../ --go_out=../ Model.proto
protoc --micro_out=../ --go_out=../ ProdService.proto
三. 实现服务端。
- 服务端代码。
package main
import (
"github.com/micro/go-micro"
"github.com/micro/go-plugins/registry/consul"
"github.com/micro/go-micro/registry"
"go-micro-grpc/Services"
"go-micro-grpc/ServiceImpl"
)
func main(){
//consul注册中心
consulReg := consul.NewRegistry(
registry.Addrs("192.168.56.10:8500"),
)
//创建web服务器
prodService := micro.NewService(
micro.Name("prodservice"), // 服务名
micro.Address(":8011"), //端口号
micro.Registry(consulReg), // 注册服务
)
//初始化服务
prodService.Init()
//绑定handler
Services.RegisterProdServiceHandler(prodService.Server(),new(ServiceImpl.ProdService))
//运行服务
prodService.Run()
}
Handler
类代码。
package ServiceImpl
import (
"context"
"go-micro-grpc/Services"
"strconv"
)
//实例化对象
func NewProd(id int32,pname string) *Services.ProdModel {
return &Services.ProdModel{
ProdID: id, //产品ID
ProdName: pname, //产品名称
}
}
type ProdService struct {
}
//生成产品列表
func (*ProdService) GetProdsList(ctx context.Context, in *Services.ProdsRequest, res *Services.ProdListResponse) error {
models := make([]*Services.ProdModel, 0)
//Size默认为2
if(in.Size <= 0){
in.Size = 2
}
var i int32
//生成Size个产品的列表
for i=0;i<in.Size;i++ {
models = append(models, NewProd(100+i, "prodname"+strconv.Itoa(100+int(i))))
}
res.Data=models
return nil
}
四. 实现客户端。
- 客户端代码。
package main
import (
"github.com/micro/go-plugins/registry/consul"
"github.com/micro/go-micro/registry"
"github.com/micro/go-micro/web"
"github.com/micro/go-micro"
"go-micro-grpc/Services"
"log"
"go-micro-grpc/Weblib"
)
func main(){
//consul注册中心
consulReg := consul.NewRegistry(
registry.Addrs("192.168.56.10:8500"),
)
myService := micro.NewService(micro.Name("prodservice.client"))
prodService := Services.NewProdService("prodservice", myService.Client())
//创建web服务器
httpServer := web.NewService(
web.Name("httpprodservice"), // 服务名
web.Address(":8001"), //端口号
web.Handler(Weblib.NewGinRouter(prodService)), // 路由
web.Registry(consulReg), // 注册服务
)
//初始化服务器
httpServer.Init()
//运行
err := httpServer.Run()
if err != nil{
log.Panic(err)
}
}
- 封装的一些代码。
handlers.go文件
package Weblib
import (
"go-micro-grpc/Services"
"github.com/gin-gonic/gin"
"context"
)
//请求服务端函数
func GetProdsList(ginCtx *gin.Context) {
//从context获取ProdService
prodService := ginCtx.Keys["prodservice"].(Services.ProdService)
//获取请求参数
var prodReq Services.ProdsRequest
err := ginCtx.Bind(&prodReq)
if err!=nil {
//返回错误信息
ginCtx.JSON(500, gin.H{"msg":err})
}else{
//返回JSON
prodRes,err := prodService.GetProdsList(context.Background(),&prodReq)
if err!=nil {
ginCtx.JSON(500, gin.H{"msg": err})
}
ginCtx.JSON(200, gin.H{"data": prodRes})
}
}
middlewares.go文件
package Weblib
import (
"go-micro-grpc/Services"
"github.com/gin-gonic/gin"
)
//中间键
func InitMiddleware(prodService Services.ProdService) gin.HandlerFunc{
//把prodService放入context
return func(context *gin.Context) {
context.Keys = make(map[string]interface{})
context.Keys["prodservice"] = prodService
context.Next()
}
}
router.go文件
package Weblib
import (
"go-micro-grpc/Services"
"github.com/gin-gonic/gin"
)
func NewGinRouter(prodService Services.ProdService) *gin.Engine {
//创建路由
ginRouter := gin.Default()
//调用中间键
ginRouter.Use(InitMiddleware(prodService))
//路由组
v1Group := ginRouter.Group("/v1")
//定义路由
v1Group.Handle("POST", "/prods", GetProdsList)
return ginRouter
}
五. 运行测试。
- 运行。
//运行服务端
go run main.go
//运行客户端
go run prod_main.go
- 结果。
git地址: https://gitee.com/php_is_no1/go-micro-grpc