项目目录
demo_grpc/
├── client
│ └── main.go
├── go.mod
├── go.sum
├── protos
│ ├── helloworld.pb.go
│ └── helloworld.proto
└── server
└── main.go
protos/helloworld.proto
syntax = "proto3";
package protos;
service HelloWorld {
rpc SayHello (HelloRequest) returns (HelloResponse) {}
}
message HelloRequest {
string name = 1;
}
message HelloResponse {
string message = 1;
}
编译protobuf
protoc --go_out=plugins=grpc:. protos/helloworld.proto
server/main.go
package main
import (
"context"
pb "github/YngwieWang/prepare/demo_grpc/protos"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
"log"
"net"
)
const grpcPort = ":50051"
type Server struct {}
func(s *Server) SayHello(ctx context.Context, in *pb.HelloRequest)(*pb.HelloResponse, error){
return &pb.HelloResponse{Message: "Hello " + in.Name}, nil
}
func main() {
listen, err := net.Listen("tcp", grpcPort)
if err!=nil{
log.Printf("failed to listen: %v", err)
return
}
grpcServer := grpc.NewServer()
pb.RegisterHelloWorldServer(grpcServer, &Server{})
reflection.Register(grpcServer)
grpcServer.Serve(listen)
}
client/main.go
package main
import (
"context"
pb "github/YngwieWang/prepare/demo_grpc/protos"
"google.golang.org/grpc"
"log"
"os"
"time"
)
const (
address = "localhost:50051"
defaultName = "XiaoMing"
)
func main() {
conn, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil {
log.Fatalf("failed to connect to server: %v", err)
}
defer conn.Close()
c := pb.NewHelloWorldClient(conn)
name := defaultName
if len(os.Args) > 1{
name = os.Args[1]
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
res, err := c.SayHello(ctx, &pb.HelloRequest{Name: name})
if err != nil {
log.Fatalf("coule not greet: %v", err)
}
log.Println(res.Message)
}
proto 文件定义了 HelloWorld 服务的接口方法 SayHello 和两个数据结构,分别是请求和响应。编译后生成 RegisterHelloWorldServer 方法和 helloWorldClient 结构体及其生成函数。
server 文件中定义了 SayHello 方法的具体实现并将一个监听指定端口的 Server 结构体通过 RegisterHelloWorldServer 方法注册为 grpc server。
client 文件中连接服务器,调用生成函数生成一个 helloWorldClient 客户端结构体,然后调用客户端结构体的 SayHello 方法取得执行结果。