blazor wasm --hosted + сеть gRCP (поток)

Можно ли выполнять потоковую передачу ответов cleint-server через сеть gRCP (http / 1.1)?

У меня есть работающее решение клиент / сервер + db, но похоже, что мне нужно дождаться полного ответа сервера (см. //await Task.Delay(2000); на сервере)

Я бы хотел, чтобы клиент отображал каждый «серверный тик», который он отправляет обратно клиенту, вместо того, чтобы ждать, пока поток закроется и отобразит полный ответ.

Есть идеи?

Proto

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);
            }
        }
    }
}

введите здесь описание изображения


person Henkolicious    schedule 29.05.2020    source источник


Ответы (1)


Итак, веб-поток gRPC действительно работает, единственное, что мне нужно было добавить, - это повторно отображать пользовательский интерфейс при каждом тике сервера.

Единственное, что вам нужно добавить в код, - это StateHasChanged();.

Обновление на стороне клиента:

while (await call?.ResponseStream?.MoveNext())
{
    reportReplys.Add(call?.ResponseStream?.Current);
    StateHasChanged();
}

Ссылка: https://docs.microsoft.com/en-us/aspnet/core/blazor/components/lifecycle?view=aspnetcore-3.1#state-changes

person Henkolicious    schedule 14.08.2020