Using gRPC under PHP/Golang platform

concept

  • gRPC: A high-performance modern RPC framework
  • Protobuf: Cross-platform data exchange protocol (service description is defined in the .protofile)

proto file example

The proto/user/user.proto file name is used as the prefix of the pb.go file name of the protoc compilation output

syntax = "proto3";

package user; //用于proto import的包名,一般和.proto文件名一致
option php_package = "./proto/user";  //相对编译指令路径的php输出目录(默认作为php名字空间),必须./开头
option go_package  = "./proto/user";  //相对编译指令路径的go输出目录(默认作为go包名),必须./开头

service UserService {
    rpc GetUser(UidRequest) returns(UserResponse);
}

message UidRequest {
    int64 id = 1;
}

message UserResponse {
    int64 id = 1;
    string name = 2;
}

PHP platform application

Environmental preparation

sudo yum -y install unzip libtool

git clone --recurse-submodules -b RELEASE_TAG版本号 https://github.com/grpc/grpc
cd grpc && make & sudo make install
# 编译输出文件中:
# grpc/bins/opt/protobuf/protoc:proto文件编译器
# grpc/bins/opt/grpc_php_plugin:PHP插件(配合protoc生成php客户端类)

sudo pecl install grpc
composer require grpc/grpc --profile --prefer-dist --optimize-autoloader
sudo pecl install protobuf
composer require google/protobuf --profile --prefer-dist --optimize-autoloader

PHP plugin to compile pb file

# 项目根目录下
protoc --plugin=protoc-gen-grpc=bins/opt/grpc_php_plugin \
       --php_out=.指定输出目录 --grpc_out=.指定输出目录 proto/user/user.proto

Service call example
The php platform only supports gRPC client, not gRPC server

//客户端
$request = (new UidRequest())->setId($id);

$client = new UserServiceClient("gRPC主机:端口", [
    'credentials' => ChannelCredentials::createInsecure(),
    'timeout' => 1000000,
]);

list($reponse, $status) = $client->GetUser($request)->wait();
$reponse->getId();
$reponse->getName();
$client->close();

Golang platform application

Environmental preparation

https://github.com/protocolbuffers/protobuf/releases #下载对应系统的protoc编译器,"mv bin/protoc $GOPATH/bin"
go get google.golang.org/protobuf/cmd/protoc-gen-go
go get google.golang.org/grpc/cmd/protoc-gen-go-grpc
go get google.golang.org/grpc

Go plugin to compile pb file

# 项目根目录下
protoc --go_out=.指定输出目录 --go-grpc_out=.指定输出目录 proto/user/user.proto

# 产出文件
# * user.pb.go:请求响应消息体定义
# * user_grpc.pb.go:客户端服务端接口定义,客户端已有完整实现,服务端有一个用于类型内嵌的空实现

Service call example

import protouser "模块名/proto/user"

//服务端
type server struct{
	protouser.UnimplementedUserServiceServer
}
func (s *server) GetUser(ctx context.Context, in *protouser.UidRequest) (*protouser.UserResponse, error) {
	return &protouser.UserResponse{Id: "", Name: ""},nil
}
func main() {
	lis, err := net.Listen("tcp", "localhost:9090")
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}
	s := grpc.NewServer()
	protouser.RegisterUserServiceServer(s, &server{})
	if err := s.Serve(lis); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}
}

//客户端
func main() {
	conn, err := grpc.Dial("localhost:9090", grpc.WithInsecure())
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	r, err := protouser.NewUserServiceClient(conn).GetUser(ctx, &protouser.UidRequest{Id: "100"})
	if err != nil {
		log.Fatalf("failed to call: %v", err)
	}
	fmt.Println(r.name)
}
{{o.name}}
{{m.name}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324147386&siteId=291194637