安装 #
protoc安装 #
安装地址:https://github.com/protocolbuffers/protobuf
右侧有个Releases,点击进入可以看到各操作系统的版本,现在相应版本protoc,我这是windows amd64
保存到GOPATH下的/bin目录下
查看版本
protoc --version
安装go版本插件 #
go get -u github.com/golang/protobuf/proto
go get -u github.com/golang/protobuf/protoc-gen-go
protobuf格式 #
在protobuf中,协议是由一系列的消息(message)
组成的,如下所示:
syntax = "proto3";
package Service;
//可以通过import导入其它proto
//import "taskModels.proto";
option go_package = "./;protos"; //两个参数一个是生成地址,一个是包名
enum Gender {
MAN = 0;
FEMAN = 1;
}
message Student {
string name = 1; //1表示标识符,同一个message中不能重复
int32 coutry = 2;
Gender gender = 3;
}
message Teacher {
string name = 1;
string class = 2;
string object = 3;
Gender gender = 4;
}
message School {
repeated Student studentList = 1;
repeated Teacher techerList = 2;
}
repeated:表示该字段可以包含多个元素,列表数组
编译生成pb.go文件 #
protoc -I ./protos --go_out=./ protos/user.proto
-I –proto_path 指定对导入文件的搜索路径,若不指定,则为当前路径
–go_out=../ 指定生成pb文件的目标目录
protos/user.proto 消息结构文件
在Service目录下执行编译命令
主函数
package main
import (
"fmt"
protos "micro_test/Service"
)
func main() {
std := &protos.Student{
Name: "laozhu",
Coutry: 0,
Gender: 0,
}
teacher := &protos.Teacher{
Name: "cjh",
Class: "1班",
Object: "语文",
Gender: 0,
}
schools := &protos.School{
StudentList: []*protos.Student{std},
TecherList: []*protos.Teacher{teacher},
}
fmt.Println(schools)
}
输出
studentList:{name:"laozhu"} techerList:{name:"cjh" class:"1班" object:"语文"}
RPC调用proto #
安装gRPC #
go get -u google.golang.org/grpc
创建proto文件 #
hello.proto
//默认是Proto2
syntax = "proto3";
// 指定包名
//package pb;
option go_package = "./;protos"; //两个参数一个是生成地址,一个是包名
// 定义消息体
message Response {
int32 error = 1; //1表示标识符,同一个message中不能重复
string ans = 2;
}
// 消息体嵌套
message Request {
string name = 1;
}
//声明rpc调用方法
service ii14 {
rpc sayHello(Request) returns (Response);
}
编译 #
使用了grpc插件 –go_out=plugins=grpc:.
protoc -I ./protos --go_out=plugins=grpc:./ protos/hello.proto
grpc测试 #
将上述protoc编译出来的go文件放到下述文件中同目录下引用使用
服务端代码 #
server/server.go
package main
import (
context "context"
"fmt"
protos "micro_test/Service"
"net"
"google.golang.org/grpc"
)
//定义服务
type RPCService struct {
}
//实现服务方法
func (srv *RPCService) SayHello(ctx context.Context, req *protos.Request) (*protos.Response, error) {
name := req.Name
return &protos.Response{Error: 0, Ans: "Hello " + name}, nil
}
func main() {
//启动grpc服务
grpcSrv := grpc.NewServer()
//实现服务接口
protos.RegisterIi14Server(grpcSrv, new(RPCService))
listener, err := net.Listen("tcp", "127.0.0.1:8080")
if err != nil {
fmt.Println("net Listen error", err)
}
//启动侦听服务
grpcSrv.Serve(listener)
}
客户端代码 #
client/server.go
package main
import (
context "context"
"fmt"
grpc "google.golang.org/grpc"
protos "micro_test/Service"
)
func main() {
//连接grpc地址
conn, err := grpc.Dial("127.0.0.1:8080", grpc.WithInsecure())
if err != nil {
fmt.Println("grpc Dial error", err)
return
}
//调用call client
client := protos.NewIi14Client(conn)
//执行客户端的函数SayHello
rep, err := client.SayHello(context.TODO(), &protos.Request{Name: "zy"})
if err == nil {
fmt.Println("execute succ ", rep)
}
}
Micro调用 #
安装micro命令 #
go get github.com/micro/protoc-gen-micro
go get github.com/micro/go-micro/v2
创建proto文件 #
用户模型userModels.proto
syntax="proto3";
package services;
option go_package="../;protos";
message UserModel{
// @inject_tag: json:"id"
uint32 ID=1;
// @inject_tag: json:"user_name"
string UserName=2;
// @inject_tag: json:"created_at"
int64 CreatedAt=3;
// @inject_tag: json:"updated_at"
int64 UpdatedAt=4;
// @inject_tag: json:"deleted_at"
int64 DeletedAt=5;
}
用户业务userService.proto
syntax = "proto3";
option go_package="../;protos";
service Greeter {
rpc Hello(Request) returns (Response) {}
}
message Request {
string name = 1;
}
message Response {
string msg = 1;
}
编译 #
在protos目录下执行
protoc --micro_out=. --go_out=. greeter.proto
调用调试 #
服务端 #
package main
import (
protos "micro_test/Service"
"github.com/micro/go-micro/v2"
"context"
)
type Greeter struct {
}
func (g *Greeter) Hello(ctx context.Context, req *protos.Greeter.Request, rsp *protos.Response) error {
rsp.Msg = "Hello " + req.Name
return nil
}
func main() {
microService := micro.NewService(
micro.Name("rpcGreeterService"), // 微服务名字
micro.Address("127.0.0.1:8082"),
)
microService.Init()
_ = protos.RegisterGreeterHandler(microService.Server(), &Greeter{})
_ = microService.Run()
}
客户端代码 #
microService := micro.NewService(
micro.Name("greeterService.client"),
)
// 用户服务调用实例
greeterService := protos.NewGreeterService("rpcGreeterService",microService.Client())
server := web.NewService(
web.Name("httpService"),
web.Address("127.0.0.1:4000"),
//将服务调用实例使用gin处理
web.Handler(router(greeterService)),
web.RegisterTTL(time.Second*30),
web.RegisterInterval(time.Second*15),
web.Metadata(map[string]string{"protocol": "http"}),
)
//接收命令行参数
_ = server.Init()
_ = server.Run()
//定义路由
func router(service interface{}) *gin.Engine {
ginRouter := gin.Default()
ginRoouer.GET("greeter",function(ctx *gin.Context) {
var req *&protos.Request
cxt.Bind(&req)
greeterService := service.(protos.GreeterService)
resp,err := greeterService.SayHello(context.Background(),&req)
ginCtx.JSON(http.StatusOK, gin.H{"data": resp})
}
}