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)
}