下载grpc通用编译器
安装go专用的protoc的生成器
- 安装命令:go get -v github.com/golang/protobuf/protoc-gen-go
- 安装后会在GOPATH目录下生成可执行文件,protobuf的编译器插件protoc-gen-go,等下执行protoc命令会自动调用这个插件
编写protobuf文件
// 语法为proto3
syntax = "proto3";
// 指定包名为pb
package pb;
// 表示在当前目录下生成.go文件,并且包名为pb
option go_package = "./;pb";
// 定义客户端传到服务端的请求体格式
message Request{
string Name = 1;
int32 Age = 2;
}
// 定义服务端响应到客户端的响应体格式
message Response{
string remarks = 3;
}
// 定义一个Hello的服务
service Hello{
// 定义Say方法
rpc Say(Request) returns(Response);
}
- 编译命令 :protoc --go_out=plugins=grpc:./ *.proto
RegisterHelloServer
用于注册服务的函数
GrpcHello
实现这个接口用于返回结果给客户端
服务端
package main
import (
"context"
"day01/server/pb"
"fmt"
"google.golang.org/grpc"
"net"
)
// 实现Hello接口用于返回结果给客户端
type GrpcHello struct {
}
// 接口具体的方法
func (this *GrpcHello) Say(cx context.Context, req *pb.Request) (*pb.Response, error) {
/*
cx context.Context 上下文管理
req *pb.Request 这个就是我们之前在protobuff中写的Request,也就是客户端传上来的请求内容都在这里面
*/
// 实例化Response对象,也就是我们在protobuff中写的Response,将返回的内容封装之后返回给客户端
res := pb.Response{
Remarks: fmt.Sprintf("姓名:%s 年龄:%d", req.Name, req.Age),
}
return &res, nil
}
func main() {
//创建一个grpc对象
grpcServer := grpc.NewServer()
// 注册服务
pb.RegisterHelloServer(grpcServer, &GrpcHello{})
// 监听
listen, err := net.Listen("tcp", "127.0.0.1:8888")
defer listen.Close()
if err != nil {
fmt.Println("创建监听失败...", err)
return
}
fmt.Println("启动监听...")
grpcServer.Serve(listen)
}
客户端
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"day01/client/pb"
)
func main() {
// 连接服务端,并且添加grpc.WithInsecure(),不然没有证书会报错
conn, err := grpc.Dial("127.0.0.1:8888", grpc.WithInsecure())
if err != nil {
fmt.Println("连接服务端出错...")
return
}
defer conn.Close()
// 创建grpc服务客户端
serverClient := pb.NewHelloClient(conn)
// 调用Say服务
response, err := serverClient.Say(context.Background(), &pb.Request{Age: 18, Name: "老王"})
if err != nil {
fmt.Println("发送消息失败...", err)
return
}
fmt.Println(response)
}