Net Core gRPC - 04. 客户端服务端双端流

Net Core gRPC 系列

1. 什么是客户端服务端双端流

gRPC支持四种通信模式,一元、服务器流式处理、客户端流式处理、双向流式处理。客户端服务端双端流是客户端发送多次请求,服务器在接收请求信息,并在返回多次响应结果。即客户端发送多次请求,而服务器响应多次。

2. Proto文件的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
syntax = "proto3";

option csharp_namespace = "WebApi.Protos";

package greet;
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";
import "google/protobuf/any.proto";
// The greeting service definition.
service Greeter {
// 双向流调用
rpc ClientServerStreamMethodAsync(stream ClientStreamMethodParam) returns (stream ServerStreamMethodResponse);
}

message ClientStreamMethodParam {
int32 par = 1;
}
message ServerStreamMethodResponse {
string Result = 1;
}

3. 服务端接口实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/// <summary>
/// 双向流 客户端发送多个int类型的值,服务器接收后处理并一次响应
/// </summary>
/// <param name="requestStream"></param>
/// <param name="responseStream"></param>
/// <param name="context"></param>
public override async Task ClientServerStreamMethodAsync(IAsyncStreamReader<ClientStreamMethodParam> requestStream, IServerStreamWriter<ServerStreamMethodResponse> responseStream,
ServerCallContext context)
{
var lst = new List<int>();
while (await requestStream.MoveNext())
{
var result = requestStream.Current.Par;
lst.Add(result);
}

foreach (var item in lst)
{
await responseStream.WriteAsync(new ServerStreamMethodResponse { Result = $"[{DateTime.Now:yyyy-M-d hh:mm:ss}] response stream result: { item } " });
await Task.Delay(500);
}
}

4. 客户端调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var clientServerStream = client.ClientServerStreamMethodAsync();
var clientServerRequestStream = clientServerStream.RequestStream;
for (int k = 0; k < 10; k++)
{
await clientServerRequestStream.WriteAsync(new ClientStreamMethodParam { Par = k });
Console.WriteLine($"send par {k}");
await Task.Delay(500);
}
await clientServerRequestStream.CompleteAsync();
var clientServerResponse = clientServerStream.ResponseStream;
while (await clientServerResponse.MoveNext(token))
{
Console.WriteLine($"{ clientServerResponse.Current.Result }");
}

完整代码可以在 GitHub

WebApplication1Test 整合了gRPC,ConsoleApp1Test有具体调用示例