1、安装编译器:
Releases · protocolbuffers/protobuf · GitHub下载地址 :Releases · protocolbuffers/protobuf · GitHub
windows电脑下载:protoc-21.2-win64.zip
解压后将bin目录添加到环境变量中,GoLand不生效就重启软件:
2、下载protoc-gen-go和grpc包:
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go get google.golang.org/grpc/cmd/protoc-gen-go-grpc
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc
go get google.golang.org/grpc
3、编写一个proto文件:GrpcDemo.proto
syntax = "proto3";
option go_package = "./serviceGrpc/;serviceGrpc";//存放目录和包名
package demo;
service DemoService {
rpc UnaryCall (DemoRequest) returns (DemoReply);
// rpc StreamingFromServer (Request) returns (stream Reply);
// rpc StreamingFromClient (stream Request) returns (Reply);
// rpc StreamingBothWays (stream Request) returns (stream Reply);
}
message DemoRequest {
string json = 1;
};
message DemoReply {
string message = 1;
}
4、根据proto文件生成go代码文件:
#将./protos/*.proto匹配到的proto文件生成输出到当前目录下的serviceGrpc文件夹下(与proto文件中的option go_package对应)。
protoc --go_out=. --go-grpc_out=. ./protos/*.proto
5、Grpc服务端:
创建一个业务处理文件:MyDemoServer.go
package serviceGrpc
import (
"context"
"fmt"
)
type MyDemoServer struct {
UnimplementedDemoServer
}
func (s *MyDemoServer) UnaryCall(ctx context.Context, req *DemoRequest) (*DemoReply, error) {
fmt.Println("request:", req.Json)
return &DemoReply{Message: "Hello " + req.Json}, nil
}
入口main.go 同时使用gin和grpc:
单独开一个协程去启动grpc,也看情况可以独立使用gin或grpc。
func main() {
go useGrpc()
useGin()
}
func useGin() {
conf, err := config.ParseConfig("./config/app.json")
if err != nil {
panic("读取配置文件失败," + err.Error())
}
//fmt.Printf("conf:%#v\n", conf)
utils.InitRedisUtil(conf.RedisConfig.Addr, conf.RedisConfig.Port, conf.RedisConfig.Password)
utils.InitMySqlUtil(conf.Database)
//创建一个默认的路由引擎
engine := gin.Default()
routers.RegisterRouter(engine)
engine.Run(":9090")
}
func useGrpc() {
const port = ":9091" // 服务器端口
listen, err := net.Listen("tcp", port)
if err != nil {
fmt.Printf("failed to listen: %v", err)
return
}
s := grpc.NewServer()
serviceGrpc.RegisterDemoServer(s, &serviceGrpc.MyDemoServer{})
//reflection.Register(s)
defer func() {
s.Stop()
listen.Close()
}()
err = s.Serve(listen)
if err != nil {
fmt.Printf("failed to server: %v", err)
return
}
}
6、使用postman模拟请求
7、创建客户端并调用:
package main
import (
"context"
"fmt"
"gin_demo/serviceGrpc"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"time"
)
const (
address = "localhost:9091"
)
func main() {
conn, err := grpc.Dial(address, grpc.WithTransportCredentials(insecure.NewCredentials())) //建立客户端和服务器之间的链接
if err != nil {
fmt.Printf("connect failed %v \n", err)
}
defer conn.Close()
c := serviceGrpc.NewDemoClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
// 远程调用UnaryCall方法
resp, err := c.UnaryCall(ctx, &serviceGrpc.DemoRequest{Json: "I am bear"})
if err != nil {
fmt.Printf("UnaryCall failed:%v", err)
}
fmt.Println("response msg: ", resp.Message)
}