項目目錄
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 方法取得執行結果。