-
1.安装protoc
地址https://github.com/protocolbuffers/protobuf/releases 下载安装文件,windows为例下载
下载后解压缩在bin目录下有protoc.exe
打开cmd将目录定位为/protoc/bin下输入命令protoc --version如下图,说明安装成功
-
2.安装插件protoc-gen-go
go get -u -v github.com/golang/protobuf/protoc-gen-go
-
3.安装protobuf库
go get -u -v github.com/golang/protobuf/proto
-
4.编写proto文件pbclass.proto
使用vscode可以安装vscode-proto3插件来编辑proto文件
syntax = "proto3";
// 请求书详情的参数结构 book_id 32 位整形
message BookInfoParams {
int32 book_id = 1;
}
// 书详情信息的结构 book_name 字符串类型
message BookInfo {
int32 book_id = 1;
string book_name = 2;
}
// 请求书列表的参数结构 page、limit 32 位整形
message BookListParams {
int32 page = 1;
int32 limit = 2;
}
// 书列表的结构 BookInfo 结构数组
message BookList {
repeated BookInfo book_list = 1;
}
// 定义 获取书详情 和 书列表服务 入参出参分别为上面所定义的结构
service BookService {
rpc GetBookInfo (BookInfoParams) returns (BookInfo) {}
rpc GetBookList (BookListParams) returns (BookList) {}
}
-
5.生成go文件
将安装好的插件protoc-gen-go.exe拷贝到protoc.exe的目录下,并把proto文件也放在该目录中
cmd中将目录定位到当前目录,并执行命令(其中pbclass.proto换为自己的文件名)
protoc --go_out=plugins=grpc:. pbclass.proto
看到文件中生成出pbclass.pb.go文件
-
6.安装grpc包
go get -u google.golang.org/grpc
很明显上面又是被墙的地址,只能曲线救国
git clone https://github.com/grpc/grpc-go.git $GOPATH/src/google.golang.org/grpc
git clone https://github.com/golang/net.git $GOPATH/src/golang.org/x/net
git clone https://github.com/golang/text.git $GOPATH/src/golang.org/x/text
go get -u github.com/golang/protobuf/{proto,protoc-gen-go}
git clone https://github.com/google/go-genproto.git $GOPATH/src/google.golang.org/genproto
go install google.golang.org/grpc
将以上项目通过github下载到本地后拷贝到代码后段的地址下,使用最后一行命令手动安装
-
7.服务器代码
package main
import (
"fmt"
"net"
"grpcdemo/pbclass"
"golang.org/x/net/context"
"google.golang.org/grpc"
)
type server struct{}
func (s *server) Login(ctx context.Context, usr *pbclass.UserInfo) (*pbclass.FuncResponse, error) {
fmt.Println("server Login() UserInfo:", usr)
usr.Id = 100
strId := "100"
return &pbclass.FuncResponse{Reply: strId}, nil
}
func (s *server) Logout(ctx context.Context, uid *pbclass.UserID) (*pbclass.FuncResponse, error) {
fmt.Println("server logout() UserID:", uid)
return &pbclass.FuncResponse{Reply: "Logout Successed."}, nil
}
func main() {
lis, err := net.Listen("tcp", ":50052")
if err != nil {
fmt.Println("failed to listen:", err)
}
s := grpc.NewServer()
pbclass.RegisterUserServiceServer(s, &server{})
fmt.Println("success")
s.Serve(lis)
}
-
8.客户端代码
package main
import (
"fmt"
"strconv"
"grpcdemo/pbclass"
"golang.org/x/net/context"
"google.golang.org/grpc"
)
func main() {
conn, err := grpc.Dial("localhost:50052", grpc.WithInsecure())
if err != nil {
fmt.Println("did not connect:", err)
}
defer conn.Close()
c := pbclass.NewUserServiceClient(conn)
var status pbclass.UserStatus
status = pbclass.UserStatus_ONLINE
userInfo := &pbclass.UserInfo{
//Id: 10, //proto.Int32(10),
Name: "XCL-gRPC", //proto.String("XCL-gRPC"),
Status: status,
}
r, err := c.Login(context.Background(), userInfo)
if err != nil {
fmt.Println("登录失败! ", err)
}
fmt.Println("Login():", r)
uid, err := strconv.ParseInt(r.Reply, 10, 32)
if err != nil {
fmt.Println("非数字 ", err)
}
userID := &pbclass.UserID{Id: int32(uid)}
out, err := c.Logout(context.Background(), userID)
fmt.Println("Logout():", out)
}
结果: