使用 protoc
指令產生出兩個檔案,這兩個檔案如何去實現Server端與Client端,當然也可以時作出Server端與Client使用不同的語言。
syntax = "proto3";
package NAME;
service ServiceName {
rpc RPCName (stream ReqData) returns (stream ResData){}
}
message ReqData {
string data = 1;
}
message ResData {
string data = 1;
}
分析輸出的檔案
// protoc-gen-go 生成的檔案
// pb.go 這個檔案定義基本的proto轉換過來的檔案格式
...
// protoc-gen-go-grpc 生成的檔案
// grpc.pb.go 控制 pb.go 中的 struct
// 針對gRPC來說,會生成這些interface,有 Client/Server 分開兩個
type ServiceName_RPCNameClient interface {
Send(*ReqData) error // Server to Client
Recv() (*ResData, error) // Client to Server
...
}
type ServiceName_RPCNameServer interface {
Send(*ReqData) error // Server to Client
Recv() (*ResData, error) // Client to Server
...
}
Server 基本使用
package main
import (
"go-grpc/pro"
"google.golang.org/grpc"
)
// PORT port號
const PORT = ":50051"
// 將grpc.pb.go 的server指進來
type server struct {
// pro.UnimplementedGreeterServer
}
// RPCName 服務端客戶端雙向流
func (s *server) RPCName(rpcName pro.ServiceName_RPCNameServer) error {
... 處理 rpcName.Send() 或 rpcName.Recv()
}
Client 基本使用
package main
import (
"google.golang.org/grpc"
"context"
"go-grpc/pro"
"log"
_ "google.golang.org/grpc/balancer/grpclb"
)
const (
ADDRESS = "localhost:50051"
)
func main() {
//建立 gRPC連線
conn, _ := grpc.Dial(ADDRESS, grpc.WithInsecure())
defer conn.Close()
//建立一個client
c := pro.NewServiceNameClient(conn)
rpcName, _ := c.RPCName(context.Background())
// ... 處理 rpcName.Send() 或 rpcName.Recv()
}