demo结构如下,基于标准库构建
测试:
1 proto文件生成
> protoc -I . --go_out=plugins=grpc:./idl/proto ./idl/data.proto
2 启动服务端
- 窗口1:
> go run ./server/server.go
3 测试客户端
- 窗口2:
> go run ./client/client.go
client.go
package main
import (
"fmt"
"golang.org/x/net/context"
"google.golang.org/grpc"
"grpc/consts"
pb "grpc/idl/proto"
)
func main() {
//连接gRPC服务器
conn, err := grpc.Dial(consts.Address, grpc.WithInsecure())
if err != nil {
fmt.Println(err)
}
defer conn.Close()
//初始化客户端
c := pb.NewHelloClient(conn)
//调用方法
reqBody := new(pb.HelloRequest)
reqBody.Name = "调用SayHello"
r, err := c.SayHello(context.Background(), reqBody)
if err != nil {
fmt.Println(err)
}
fmt.Println(r.Message)
nameReq := new (pb.NameReq)
nameReq.Name = "调用YourName"
nameRet,_ := c.YourName(context.Background(), nameReq)
fmt.Println(nameRet.Ret)
}
consts.go
package consts
const (
//gRPC服务地址
Address = "127.0.0.1:8081"
)
data.proto
syntax = "proto3"; //指定proto版本
option go_package = "./;proto";
//SayHello 对应的请求和响应
//定义请求结构
message HelloRequest{
string name=1;
}
//定义响应结构
message HelloReply{
string message=1;
}
//YourName 对应的请求和响应
message NameReq{
string name=1;
}
message NameRes{
string ret=1;
}
//定义Hello服务
service Hello{
//定义服务中的方法
rpc SayHello(HelloRequest) returns (HelloReply){}
rpc YourName(NameReq) returns (NameRes){}
}
server.go
package main
import (
"fmt"
"golang.org/x/net/context"
"google.golang.org/grpc"
"grpc/consts"
pb "grpc/idl/proto"
"net"
)
//定义一个helloServer并实现约定的接口
type helloService struct{}
func (h helloService) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
resp := new(pb.HelloReply)
resp.Message = "SayHello:" + in.Name + "."
return resp, nil
}
func (h helloService) YourName(ctx context.Context, in *pb.NameReq) (*pb.NameRes, error) {
resp := new(pb.NameRes)
resp.Ret = "YourName:" + in.Name + "."
return resp, nil
}
var HelloServer = helloService{}
func main() {
listen, err := net.Listen("tcp", consts.Address)
if err != nil {
fmt.Printf("failed to listen:%v", err)
return
}
//实现gRPC Server
s := grpc.NewServer()
//注册helloServer为客户端提供服务
pb.RegisterHelloServer(s, HelloServer) //内部调用了s.RegisterServer()
fmt.Println("Listen on " + consts.Address)
s.Serve(listen)
}
go.mod
module grpc
go 1.17
require (
golang.org/x/net v0.0.0-20211029224645-99673261e6eb
google.golang.org/grpc v1.41.0
google.golang.org/protobuf v1.27.1
)
require (
github.com/golang/protobuf v1.5.0 // indirect
golang.org/x/sys v0.0.0-20210423082822-04245dca01da // indirect
golang.org/x/text v0.3.6 // indirect
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect
)