gRPC 是一种基于 Protocol Buffers 的高性能 RPC 框架,支持多种编程语言和平台。在 gRPC 中,我们可以使用一元请求和流式请求两种方式来实现远程过程调用。

1. 一元请求

一元请求是指客户端发送一个请求,并且服务器返回一个响应。这种方式最常见的场景是客户端向服务器查询数据或者执行一个操作。

以下是一个简单的 gRPC 一元请求示例:

syntax = "proto3";

service Greeter {
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
    string name = 1;
}

message HelloReply {
    string message = 1;
}
GreeterSayHelloHelloRequestHelloReply
SayHello()
package main

import (
	"context"
	"log"

	pb "example/proto"

	"google.golang.org/grpc"
)

func main() {
	conn, err := grpc.Dial(":8080", grpc.WithInsecure())
	if err != nil {
		log.Fatalf("failed to connect: %v", err)
	}
	defer conn.Close()

	client := pb.NewGreeterClient(conn)
	resp, err := client.SayHello(context.Background(), &pb.HelloRequest{Name: "World"})
	if err != nil {
		log.Fatalf("failed to call SayHello: %v", err)
	}

	log.Printf("response message: %s", resp.Message)
}
pb.NewGreeterClient()SayHello()World

2. 流式请求

流式请求是指客户端发送多个请求,并且服务器通过一系列响应进行回应。这种方式适合于需要处理大量数据或者长时间运行的操作。

gRPC 提供了两种类型的流式请求:客户端流和服务器端流。在客户端流中,客户端将多个消息打包成单个请求发送给服务器,而服务器则返回一个响应。在服务器端流中,服务器将多个消息打包成单个响应发送给客户端,而客户端则返回一个空值。

以下是一个简单的 gRPC 客户端流式请求示例:

syntax = "proto3";

service Calculator {
    rpc Sum (stream Number) returns (Result) {}
}

message Number {
    int32 value = 1;
}

message Result {
    int32 sum = 1;
}
CalculatorSumNumberResult
Sum()
package main

import (
	"context"
	"io"
	"log"

	pb "example/proto"

	"google.golang.org/grpc"
)

func main() {
	conn, err := grpc.Dial(":8080", grpc.WithInsecure())
	if err != nil {
		log.Fatalf("failed to connect: %v", err)
	}
	defer conn.Close()

	client := pb.NewCalculatorClient(conn)
	stream, err := client.Sum(context.Background())
	if err != nil {
		log.Fatalf("failed to call Sum: %v", err)
	}

	for i := 1; i <= 10; i++ {
		err = stream.Send(&pb.Number{Value: int32(i)})
		if err != nil {
			log.Fatalf("failed to send number: %v", err)
		}
	}

	resp, err := stream.CloseAndRecv()
	if err != nil {
		log.Fatalf("failed to receive result: %v", err)
	}

	log.Printf("sum: %d", resp.Sum)
}
pb.NewCalculatorClient()Sum()

3. 总结

gRPC 支持一元请求和流式请求两种方式来实现远程过程调用。一元请求是指客户端发送一个请求,并且服务器返回一个响应;流式请求是指客户端发送多个请求,并且服务器通过一系列响应进行回应。在实现 gRPC 客户端时,我们可以通过调用自动生成的代码中的方法来发送一元请求或者流式请求并接收响应。