grpc
Go gRPC使用demo
准备工作:
1. 安装protobuf 编译环境 https://github.com/protocolbuffers/protobuf/releases
2. 安装go语言的protobuf代码转换工具protoc-gen-go go get -u github.com/golang/protobuf/protoc-gen-go
3. 运行go mod init grpc_demo创建模块
使用
1. 定义和编译user.proto文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
// 定义proto语法版本,这里指定使用proto3版本 syntax = "proto3" ; // 这里随便定义个包名 package grpc.user; // go需要增加这个选项,否则会报错;值用分号分隔,前者表示生成*.pb.go文件目录,会自动创建,这里指定当前目录中的protobuf目录,后者表示生成go文件里的包名,最好和当前目录名一致否则无法使用到 option go_package = "./protobuf;protobuf" ; // 定义服务,可以有多个方法 service UserService { // 使用rpc开头标识方法 rpc Login(LoginRequest) returns (LoginResponse) {}; } // 定义请求信息 message LoginRequest { // 参数类型 参数名称 标识号 string username = 1; string password = 2; } // 定义响应信息 message LoginResponse { // 参数类型 参数名称 标识号 int32 code = 1; string message = 2; } // 最后使用 protoc --go_out=plugins=grpc:. ./protobuf/user.proto 来生成*.pb.go文件 |
运行 protoc --go_out=plugins=grpc:. ./protobuf/user.proto 来生成*.pb.go文件
2. 定义服务及实现
user_service.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
// 这里定义服务接口及实现 package service import ( "context" "grpc_demo/protobuf" ) // 定义服务接口 type UserService interface { Login(ctx context.Context, req *protobuf.LoginRequest) (*protobuf.LoginResponse, error) } // 定义服务实现者,这里开头小写,不能被别的包使用,所以会增加一个工厂函数来创建实例 type userService struct { } // 工厂函数创建服务实例 func NewUserService() UserService { return &userService{} } // 实现者实现服务接口 func (userService *userService) Login(ctx context.Context, req *protobuf.LoginRequest) (*protobuf.LoginResponse, error) { if req.Username == "admin" && req.Password == "123456" { resp := &protobuf.LoginResponse{ Code: 10000, Message: "登录成功" , } return resp, nil } resp := &protobuf.LoginResponse{ Code: 10001, Message: "登录失败" , } return resp, nil } |
3. 定义gRPC服务端并运行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
// gRPC服务端 package main import ( "fmt" "google.golang.org/grpc" "grpc_demo/protobuf" "grpc_demo/service" "log" "net" ) func main() { // 1. 监听端口 l, err := net.Listen( "tcp" , "127.0.0.1:8888" ) if err != nil { panic(err) } fmt.Println( "listen on 127.0.0.1:8888" ) // 2. 实例化gRPC服务端 grpcServer := grpc.NewServer() // 3. 注册实现的服务实例 var userService service.UserService userService = service.NewUserService() protobuf.RegisterUserServiceServer(grpcServer, userService) // 4. 启动gRPC服务端 fmt.Println( "gRPC is running..." ) err = grpcServer.Serve(l) if err != nil { log.Fatalf( "gRPC server err:%s\n" , err) } } |
4. 定义gRPC客户端并发送消息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
// gRPC客户端 package main import ( "context" "fmt" "google.golang.org/grpc" "grpc_demo/protobuf" ) func main() { // 1. 打开gRPC服务端链接 conn, err := grpc.Dial( "127.0.0.1:8888" , grpc.WithInsecure()) if err != nil { panic(err) } defer conn.Close() // 2. 创建gRPC客户端 client := protobuf.NewUserServiceClient(conn) // 3. 构造请求参数 req := &protobuf.LoginRequest{ Username: "admin" , Password: "123456" , } // 4. 调用服务端提供的服务 response, _ := client.Login(context.Background(), req) fmt.Println( "Login Response: " , response) } |
目录结构