blazor wasm --hosted + gRCP 网络(流)
blazor wasm --hosted + gRCP web (stream)
是否可以通过 gRCP 网络 (http/1.1) 进行客户端服务器流式响应?
我有一个有效的 client/server + 数据库解决方案,但似乎我必须等待完整的服务器响应(请参阅服务器中的 //await Task.Delay(2000);
)
我想要发生的是,客户端应该在它发送回客户端的每个 "server-tick" 上呈现,而不是等待流关闭并呈现完整的响应。
有什么想法吗?
原型
syntax = "proto3";
option csharp_namespace = "GrpcReports";
package reports;
service Reports {
rpc AllReports (ReportRequest) returns (stream ReportReply);
}
message ReportRequest {}
message ReportReply {
string name = 1;
}
服务器
// server
public class ReportsService : Reports.ReportsBase
{
private readonly IReportRepository _repository;
private readonly IMapper _mapper;
public ReportsService(IReportRepository repository, IMapper mapper)
{
_repository = repository ?? throw new ArgumentNullException(nameof(IReportRepository));
_mapper = mapper ?? throw new ArgumentNullException(nameof(IMapper));
}
public override async Task AllReports(ReportRequest request, IServerStreamWriter<ReportReply> responseStream, ServerCallContext context)
{
foreach (var item in _mapper.Map<List<ReportReply>>(await _repository.GetAllReportsAsync()))
{
Log.Information("{@ReportReply}", item);
await responseStream.WriteAsync(item);
//await Task.Delay(2000);
}
}
}
客户端
@page "/"
@using Grpc.Core
@using GrpcReports
@using AutoMapper
@inject Reports.ReportsClient _reportsClient
@inject IMapper _mapper
<h1>Invoke gRPC service</h1>
<button @onclick="AllReports" class="btn btn-primary">Call gRPC service</button>
<p>Server report response from database:</p>
<ul>
@foreach (var item in reportReplys)
{
<li>@item.Name</li>
}
</ul>
@code {
List<ReportReply> reportReplys = new List<ReportReply>();
async Task AllReports()
{
using (var call = _reportsClient.AllReports(new ReportRequest()))
{
while (await call.ResponseStream.MoveNext())
{
reportReplys.Add(call?.ResponseStream?.Current);
}
}
}
}
所以 gRPC 网络流确实有效,我唯一需要添加的是 re-render 每个服务器 tick 上的 UI。
您唯一需要添加到代码中的是 StateHasChanged();
。
客户端 端更新:
while (await call?.ResponseStream?.MoveNext())
{
reportReplys.Add(call?.ResponseStream?.Current);
StateHasChanged();
}
是否可以通过 gRCP 网络 (http/1.1) 进行客户端服务器流式响应?
我有一个有效的 client/server + 数据库解决方案,但似乎我必须等待完整的服务器响应(请参阅服务器中的 //await Task.Delay(2000);
)
我想要发生的是,客户端应该在它发送回客户端的每个 "server-tick" 上呈现,而不是等待流关闭并呈现完整的响应。
有什么想法吗?
原型
syntax = "proto3";
option csharp_namespace = "GrpcReports";
package reports;
service Reports {
rpc AllReports (ReportRequest) returns (stream ReportReply);
}
message ReportRequest {}
message ReportReply {
string name = 1;
}
服务器
// server
public class ReportsService : Reports.ReportsBase
{
private readonly IReportRepository _repository;
private readonly IMapper _mapper;
public ReportsService(IReportRepository repository, IMapper mapper)
{
_repository = repository ?? throw new ArgumentNullException(nameof(IReportRepository));
_mapper = mapper ?? throw new ArgumentNullException(nameof(IMapper));
}
public override async Task AllReports(ReportRequest request, IServerStreamWriter<ReportReply> responseStream, ServerCallContext context)
{
foreach (var item in _mapper.Map<List<ReportReply>>(await _repository.GetAllReportsAsync()))
{
Log.Information("{@ReportReply}", item);
await responseStream.WriteAsync(item);
//await Task.Delay(2000);
}
}
}
客户端
@page "/"
@using Grpc.Core
@using GrpcReports
@using AutoMapper
@inject Reports.ReportsClient _reportsClient
@inject IMapper _mapper
<h1>Invoke gRPC service</h1>
<button @onclick="AllReports" class="btn btn-primary">Call gRPC service</button>
<p>Server report response from database:</p>
<ul>
@foreach (var item in reportReplys)
{
<li>@item.Name</li>
}
</ul>
@code {
List<ReportReply> reportReplys = new List<ReportReply>();
async Task AllReports()
{
using (var call = _reportsClient.AllReports(new ReportRequest()))
{
while (await call.ResponseStream.MoveNext())
{
reportReplys.Add(call?.ResponseStream?.Current);
}
}
}
}
所以 gRPC 网络流确实有效,我唯一需要添加的是 re-render 每个服务器 tick 上的 UI。
您唯一需要添加到代码中的是 StateHasChanged();
。
客户端 端更新:
while (await call?.ResponseStream?.MoveNext())
{
reportReplys.Add(call?.ResponseStream?.Current);
StateHasChanged();
}