1. 安装protobuf(必备前置)和grpc:
- 安装protobuf
go get -u github.com/golang/protobuf/proto
- 安装protobuf的插件protoc-gen-go
go get -u github.com/golang/protobuf/protoc-gen-go
- 安装grpc
go get -u google.golang.org/grpc
2. 创建示例
- 目录结构
- 创建proto文件,根据该文件可以约定传输的参数规则,参数都是从1开始(common/common.proto)
syntax = "proto3"; // 指定proto版本
package common; // 包名
option go_package="./;common"; // 文件输出路径和包名,使用分号分隔开
service UserService { // 服务名
rpc GetUser (GetUserRequest) returns (GetUserResponse);
rpc GetNames (GetNamesRequest) returns (GetNamesResponse);
}
message GetUserRequest { // GetUser方法的请求参数
int64 id = 1;
string name = 2;
}
message ImageObj {
int64 id = 1;
int64 index = 2;
string url = 3;
}
message UserObj {
int64 id = 1;
string name = 2;
repeated ImageObj images = 3; // 结果是数组则使用repeated
}
message GetUserResponse { // GetUser方法的返回参数
int64 code = 1;
string msg = 2;
repeated UserObj data = 3; // repeated 表示该参数类型为数组或切片
}
message GetNamesRequest { // GetNames方法的请求参数
}
message GetNamesResponse { // GetNames方法的返回参数
int64 code = 1;
string msg = 2;
repeated string data = 3;
map <int, string> m = 4; // map格式数据
}
- 根据proto文件生成go文件
// 进入proto文件所在目录
protoc --go_out=plugins=grpc:. *proto
- go客户端(client/mian.go)
package main
import (
"context"
"fmt"
"grpcDemo/common"
"time"
"google.golang.org/grpc"
)
func main() {
conn, _ := grpc.Dial("localhost:8080", grpc.WithInsecure()) //建立链接
defer conn.Close()
c := common.NewUserServiceClient(conn) // 创建一个客户端
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
// 调用GetUser
resp1, _ := c.GetUser(ctx, &common.GetUserRequest{Id: 100})
fmt.Println(resp1.Code)
fmt.Println(resp1.Msg)
fmt.Println(resp1.Data)
// 调用GetNames
resp2, _ := c.GetNames(ctx, &common.GetNamesRequest{})
fmt.Println(resp2.Data[0])
}
- go 服务端(server/mian.go),实现了proto文件中定义的两个方法
package main
import (
"grpcDemo/common"
"net"
"golang.org/x/net/context"
"google.golang.org/grpc"
)
type server struct {
}
// GetUser
func (s *server) GetUser(ctx context.Context, in *common.GetUserRequest) (*common.GetUserResponse, error) {
var images []*common.ImageObj
for i := 0; i < 5; i++ {
a := int64(i)
images = append(images, &common.ImageObj{Id: a, Index: a})
}
var data = []*common.UserObj{&common.UserObj{Id: 1, Name: "weiwei1", Images: images}, &common.UserObj{Id: 2, Name: "weiwei2", Images: images}}
resp := &common.GetUserResponse{Code: 1, Msg: "suc", Data: data}
return resp, nil
}
// GetNames
func (s *server) GetNames(ctx context.Context, in *common.GetNamesRequest) (*common.GetNamesResponse, error) {
var names = []string{"weiwei1", "weiwei2", "weiwei3"}
return &common.GetNamesResponse{Code: 1, Msg: "suc", Data: names}, nil
}
//listen
func main() {
listen, _ := net.Listen("tcp", "localhost:8080") // 创建监听
s := grpc.NewServer() // 创建grpc服务
common.RegisterUserServiceServer(s, &server{}) // 注册服务
_ = s.Serve(listen) // 启动监听
}
3. 启动
// 1. 先将服务端启动(go run main.go)
// 2. 再执行客户端方法(go run main.go),即可看见调用结果