返回
Featured image of post gRPC - ProtoBuf 轉譯後使用 node 篇

gRPC - ProtoBuf 轉譯後使用 node 篇

gRPC node 篇

使用 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;
}

Server 基本使用

產出的grpc.pb.go中可以看到,需對於interface和struct要有一定的了解。

type ServiceNameServer interface {
	RPCName(ServiceNameServer_RPCNameServer) error
	mustEmbedUnimplementedServiceNameServer()
}
type UnimplementedServiceNameServer struct {
}

// ... 相關功能

type ServiceNameServer_RPCNameServer interface {
	Send(*ResData) error
	Recv() (*ReqData, error)
	grpc.ServerStream
}

func (*UnimplementedServiceNameServer) RPCName(ServiceNameServer_RPCNameServer) error {
	... // 系統自動生成功能 
}

server/main.go

package main

import (
	"go-grpc/pro"

	"google.golang.org/grpc"
)

// PORT port號
const PORT = ":50051"

type server struct {
	pro.UnimplementedServiceNameServer  // 將 grpc.pb.go 的 struct 註冊過來
}

func (s *server) RPCName(allStr pro.ServiceNameServer_RPCNameServer) error {
   // 處理 allStr.Recv() 和 處理 allStr.Send()
}

func main() {
	// 監聽口
	lis, err := net.Listen("tcp", PORT)
	if err != nil {
		return
	}
	// 建立一個 grpc 服務器
	s := grpc.NewServer()
	// 註冊事件
	pro.RegisterServiceServer(s, &server{})
	// 處理連結
	s.Serve(lis)
}

Client 基本使用

產出的grpc.pb.go中可以看到,需對於interface和struct要有一定的了解。

type ServiceNameClient interface {
	RPCName(ctx context.Context, opts ...grpc.CallOption) (ServiceName_RPCNameClient, error)
}

type serviceNameClient struct {
	cc grpc.ClientConnInterface
}
func (c *serviceNameClient) RPCName(ctx context.Context, opts ...grpc.CallOption) (ServiceName_RPCNameClient, error) {
	// ... 系統自動生成
	x := &serviceNameRPCNameClient{stream}
	return x, nil
}

type ServiceName_RPCNameClient interface {
	Send(*ReqData) error
	Recv() (*ResData, error)
	grpc.ClientStream
}

type serviceNameRPCNameClient struct {
	grpc.ClientStream
}

client/main.go

package main

import (
	"context"
	"google.golang.org/grpc"

	"go-grpc/pro"

	_ "google.golang.org/grpc/balancer/grpclb"
)

const (
	ADDRESS = "0.0.0.0:50051"
)

func main() {
	//建立 gRPC連線
	conn, err := grpc.Dial(ADDRESS, grpc.WithInsecure())
	if err != nil {
		return
	}
	defer conn.Close()
	//建立一個client。
	c := pro.NewServiceNameClient(conn)
	allStr, err := c.RPCName(context.Background())
	if err != nil {
		fmt.Println(err)
	}
	go func() {
		// data, err := allStr.Recv()
	}()

	go func() {
		// allStr.Send()
	}()

}
Licensed under CC BY-NC-SA 4.0
comments powered by Disqus