深度优先

这个家伙好懒,除了文章什么都没留下

0%

【.Net Core】ASP.NET Core 3.x-gRPC小例子

创建两个Web项目,Grpc.Demo.Client和Grpc.Demo.Server,项目结构如图:

Protos/greet.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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
syntax = "proto3";

option csharp_namespace = "Grpc.Demo.Server";

package greet;

// The greeting service definition.
service GreetService {
rpc SayHello (HelloRequest) returns (HelloResponse);
rpc GetByNo (GetByNoRequest) returns (EmployeeResponse);
rpc GetAll (GetAllRequest) returns (stream EmployeeResponse);
rpc AddPhoto (stream AddPhotoRequest) returns (AddPhotoResponse);
rpc Save (EmployeeRequest) returns (EmployeeResponse);
rpc SaveAll (stream EmployeeRequest) returns (stream EmployeeResponse);
}

message HelloRequest {
string name = 1;
}

message HelloResponse {
string message = 1;
}

message Employee {
int32 id = 1;
int32 no = 2;
string firstName = 3;
string lastName = 4;
float salary = 5;
}

message GetByNoRequest{
int32 no = 1;
}

message EmployeeResponse{
Employee employee = 1;
}

message GetAllRequest {

}

message AddPhotoRequest {
bytes data = 1;
}

message AddPhotoResponse {
bool isOk = 1;
}

message EmployeeRequest {
Employee employee = 1;
}

MyGreetService.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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
using Grpc.Core;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace Grpc.Demo.Server.Service
{
public class MyGreetService : GreetService.GreetServiceBase
{
private readonly ILogger<MyGreetService> _logger;

public MyGreetService(ILogger<MyGreetService> logger)
{
_logger = logger;
}

public override Task<HelloResponse> SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloResponse
{
Message = "Hello " + request.Name + Guid.NewGuid().ToString()
});
}

public override Task<EmployeeResponse> GetByNo(GetByNoRequest request, ServerCallContext context)
{
return Task.FromResult(new EmployeeResponse
{
Employee = new Employee()
{
Id = 123,
No = 123456,
FirstName = Guid.NewGuid().ToString(),
}
});
}

public override async Task GetAll(GetAllRequest request, IServerStreamWriter<EmployeeResponse> responseStream, ServerCallContext context)
{
for (int i = 0; i < 10; i++)
{
await responseStream.WriteAsync(new EmployeeResponse()
{
Employee = new Employee()
{
No = i,
}
});
}
}

public override async Task<AddPhotoResponse> AddPhoto(IAsyncStreamReader<AddPhotoRequest> requestStream, ServerCallContext context)
{
var data = new List<byte>();
while (await requestStream.MoveNext())
{
data.AddRange(requestStream.Current.Data);
}
using MemoryStream memoryStream = new MemoryStream(data.ToArray());

using FileStream fileStream = new FileStream("test.png", FileMode.OpenOrCreate);
memoryStream.WriteTo(fileStream);

return new AddPhotoResponse()
{
IsOk = true
};
}

public override async Task<EmployeeResponse> Save(EmployeeRequest request, ServerCallContext context)
{
var employee = request.Employee;
employee.FirstName = employee.FirstName + "1";
return new EmployeeResponse()
{
Employee = employee
};
}

public override async Task SaveAll(IAsyncStreamReader<EmployeeRequest> requestStream,
IServerStreamWriter<EmployeeResponse> responseStream, ServerCallContext context)
{
var employees = new List<Employee>() {
new Employee(){Id =1}
};
while (await requestStream.MoveNext())
{
employees.Add(requestStream.Current.Employee);
}
foreach (var employee in employees)
{
await responseStream.WriteAsync(new EmployeeResponse()
{
Employee = employee
});
}
}
}
}

服务端Startup.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
50
51
52
53
54
55
56
57
58
59
60
61
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Grpc.Demo.Server.Service;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace Grpc.Demo.Server
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

public void ConfigureServices(IServiceCollection services)
{
//添加grpc
services.AddGrpc();

services.AddControllersWithViews();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
//注册服务
endpoints.MapGrpcService<MyGreetService>();

endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}

客户端HomeController.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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Grpc.Demo.Client.Models;
using Grpc.Net.Client;
using Grpc.Core;
using System.IO;
using Google.Protobuf;

namespace Grpc.Demo.Client.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;

public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}

public async Task<IActionResult> Index(int id)
{
var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new GreetService.GreetServiceClient(channel);
string msg = string.Empty;
switch (id)
{
case 1:
msg = await SayHelloAsync(client);
break;

case 2:
msg = await GetByNoAsync(client);
break;

case 3:
msg = await GetAllAsync(client);
break;

case 4:
msg = await AddPhotoAsync(client);
break;

case 5:
msg = await SaveAsync(client);
break;

case 6:
msg = await SaveAllAsync(client);
break;

default:
break;
}

ViewData["Message"] = msg;
return View();
}

private async Task<string> SaveAllAsync(GreetService.GreetServiceClient client)
{
var employees = new List<Employee>()
{
new Employee(){Id=2, FirstName ="zhangsan"},
new Employee(){Id=3, FirstName ="lisi"},
};

var cell = client.SaveAll();
var requestStream = cell.RequestStream;
var responseStream = cell.ResponseStream;

var result = new List<Employee>();

var responseTask = Task.Run(async () =>
{
while (await responseStream.MoveNext())
{
result.Add(responseStream.Current.Employee);
}
});

foreach (var employee in employees)
{
await requestStream.WriteAsync(new EmployeeRequest()
{
Employee = employee
});
}

await requestStream.CompleteAsync();
await responseTask;

return string.Join(",", result.Select(p => p.Id).ToList());
}

private async Task<string> SaveAsync(GreetService.GreetServiceClient client)
{
var cell = await client.SaveAsync(new EmployeeRequest()
{
Employee = new Employee
{
FirstName = "zhangsan",
}
});
return cell.Employee.FirstName;
}

private async Task<string> AddPhotoAsync(GreetService.GreetServiceClient client)
{
FileStream fs = System.IO.File.OpenRead("test.png");
using var cell = client.AddPhoto();
var stream = cell.RequestStream;
while (true)
{
byte[] buffer = new byte[1024];
int numRead = await fs.ReadAsync(buffer, 0, buffer.Length);
if (numRead == 0)
{
break;
}
if (numRead < buffer.Length)
{
Array.Resize(ref buffer, numRead);
}
await stream.WriteAsync(new AddPhotoRequest()
{
Data = ByteString.CopyFrom(buffer)
});
}

await stream.CompleteAsync();
var response = await cell.ResponseAsync;
return response.IsOk.ToString();
}

private async Task<string> GetAllAsync(GreetService.GreetServiceClient client)
{
using var response = client.GetAll(new GetAllRequest());
var responseStream = response.ResponseStream;
List<Employee> list = new List<Employee>();
while (await responseStream.MoveNext())
{
list.Add(responseStream.Current.Employee);
}
return string.Join(",", list.Select(p => p.Id).ToList());
}

private async Task<string> GetByNoAsync(GreetService.GreetServiceClient client)
{
var response = await client.GetByNoAsync(new GetByNoRequest()
{
No = 1
});
return response.Employee.LastName;
}

private async Task<string> SayHelloAsync(GreetService.GreetServiceClient client)
{
var response = await client.SayHelloAsync(new HelloRequest { Name = "World" });
return response.Message;
}
}
}

主要代码如上!