gRPC快速入门:02——Simple RPC

本文介绍 gRPC 四种模式…

gRPC 模式

gRPC主要有4种请求 / 响应模式,分别是:

  • 简单模式 (Simple RPC)
    这种模式最为传统,即客户端发起一次请求,服务端响应一个数据,类似Http请求。

  • 服务端数据流模式 (Server-side streaming RPC)
    这种模式是客户端发起一次请求,服务端返回一段连续的数据流。典型的例子是客户端向服务端发送一个股票代码,服务端就把该股票的实时数据源源不断的返回给客户端。

  • 客户端数据流模式 (Client-side streaming RPC)
    与服务端数据流模式相反,这次是客户端源源不断的向服务端发送数据流,而在发送结束后,由服务端返回一个响应。典型的例子是物联网终端向服务器报送数据。

  • 双向数据流模式 (Bidirectional streaming RPC)
    顾名思义,这是客户端和服务端都可以向对方发送数据流,这个时候双方的数据可以同时互相发送,也就是可以实现实时交互。典型的例子是聊天机器人。

本章先使用 简单模式 (Simple RPC) 实现一个 Hello World 例子,
下一章则使用 双向数据流模式 (Bidirectional streaming RPC) 来实现一个聊天室例子。

简单模式 (Simple RPC) 例子

新建需要的文件:

1
2
3
4
5
6
7
8
9
10
11
Chat.sln
├── Chat.Client.csproj
| └── Program.cs
|
├── Chat.Protocol.csproj
| └── addressbook.proto
| └── chat.proto // 新增,用于定义 通信协议 和 数据序列化方式
|
└── Chat.Server.csproj
└── ChatRoomImpl.cs // 新增,用于实现 chat.proto 定义
└── Program.cs

chat.proto 文件内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
syntax = "proto3";
package Chat.Protocol;

service ChatRoom {

// 简单模式 (Simple RPC)
// 这种模式最为传统,即客户端发起一次请求,服务端响应一个数据,类似Http请求。
// 我们来进行 图灵测试 吧
rpc TuringTest(Request) returns (Response){}

// 服务端数据流模式 (Server-side streaming RPC)
// 这种模式是客户端发起一次请求,服务端返回一段连续的数据流。
// 典型的例子是客户端向服务端发送一个股票代码,服务端就把该股票的实时数据源源不断的返回给客户端。
rpc StockInfo(Request) returns (stream Response){}

// 客户端数据流模式 (Client-side streaming RPC)
// 与服务端数据流模式相反,这次是客户端源源不断的向服务端发送数据流,而在发送结束后,由服务端返回一个响应。
// 典型的例子是物联网终端向服务器报送数据。
rpc Report(stream Request) returns (Response){}


// 双向数据流模式 (Bidirectional streaming RPC)
// 顾名思义,这是客户端和服务端都可以向对方发送数据流,这个时候双方的数据可以同时互相发送,也就是可以实现实时交互。
// 典型的例子是聊天机器人。
rpc ShallWeTalk(stream Request) returns (stream Response) {}
}

// 请求数据 Request格式定义
message Request {
string input = 1;
}

// 响应数据Response格式定义
message Response {
string output = 1;
}

Chat.Server.ChatRoomImpl.cs 文件内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using System;
using System.Threading.Tasks;

using Grpc.Core;
using Chat.Protocol;

namespace Chat.Server
{
public class ChatRoomImpl : ChatRoom.ChatRoomBase
{
/// <summary>
/// 人工智能回复
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private string AiReply(string input)
{
//为了写例子,我将价值上亿的人工智能代码都贡献出来了,不点个赞么(手动滑稽)
input = input.Replace("吗", string.Empty);
input = input.Replace("?", "!");
input = input.Replace("?", "!");

return input;
}

/// <summary>
/// 实现 TuringTest 接口
/// </summary>
/// <param name="request"></param>
/// <param name="context"></param>
/// <returns></returns>
public override Task<Response> TuringTest(Request request, ServerCallContext context)
{
Console.WriteLine("收到问题:" + request.Input);

var reply = AiReply(request.Input);
Console.WriteLine("回复问题:" + reply);
Console.WriteLine();

return Task.FromResult(new Response { Output = reply });
}
}
}

Chat.Server.Program.cs 文件内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;

using Grpc.Core;
using Chat.Protocol;

namespace Chat.Server
{
class Program
{
static void Main(string[] args)
{
const int Port = 50052;
Grpc.Core.Server server = new Grpc.Core.Server
{
Services = { ChatRoom.BindService(new ChatRoomImpl()) },
Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) }
};

server.Start();

Console.WriteLine("server listening on port " + Port);
Console.WriteLine("Press any key to stop the server...");
Console.ReadKey();

server.ShutdownAsync().Wait();
}
}
}

Chat.Client.Program.cs 文件内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
using System;

using Grpc.Core;
using Chat.Protocol;

namespace Chat.Client
{
class Program
{
static void Main(string[] args)
{
var channel = new Channel("127.0.0.1:50052", ChannelCredentials.Insecure);
var client = new ChatRoomClient(new ChatRoom.ChatRoomClient(channel));

Console.WriteLine("请输入问题,输入 exit 则退出");

var input = string.Empty;
while (input != "exit")
{
input = Console.ReadLine().Trim();
if (!string.IsNullOrWhiteSpace(input))
{
var reply = client.Ask(input);
Console.WriteLine(reply);
Console.WriteLine();
}
}


channel.ShutdownAsync().Wait();
}
}

public class ChatRoomClient
{
readonly ChatRoom.ChatRoomClient client;

public ChatRoomClient(ChatRoom.ChatRoomClient client)
{
this.client = client;
}

public string Ask(string q)
{
var resp = client.TuringTest(new Request { Input = q });
return resp.Output;
}
}
}

先运行服务端:

1
> xxx\Chat\Chat.Server\bin\Debug\netcoreapp2.1> dotnet Chat.Server.dll

再运行客户端:

1
> xxx\Chat\Chat.Client\bin\Debug\netcoreapp2.1> dotnet Chat.Client.dll

体验一下来自人工智能的回复:

1
2
3
4
5
6
7
8
在吗?
在!

你好
你好

能听懂汉语吗
能听懂汉语

结束语

貌似都贴代码,也不讲解概念,机制什么的(以后有机会再补,哇咔咔)。
下一章则是本入门教程第三个目标:聊天室。

觉得文章对您有帮助,请我喝瓶肥宅快乐水可好 (๑•̀ㅂ•́)و✧
  • 本文作者: 阿彬~
  • 本文链接: https://iweixubin.github.io/posts/grpc/quickstart-hello-world/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 免责声明:本媒体部分图片,版权归原作者所有。因条件限制,无法找到来源和作者未进行标注。
         如果侵犯到您的权益,请与我联系删除