Есть ли способ определить на клиенте, что сервер преждевременно завершил потоковый вызов клиента, вернув ответ? ⇐ C#

Место общения программистов C#
Anonymous
Есть ли способ определить на клиенте, что сервер преждевременно завершил потоковый вызов клиента, вернув ответ?

Сообщение Anonymous »

У меня следующий случай. Клиент загружает файлы на сервер с помощью потоковой передачи данных (через grpc-dotnet). В некоторых случаях сервер может решить игнорировать клиентский поток и немедленно вернуть ответ. Поскольку клиент не знает о решении сервера, он продолжает вызывать RequestStream.WriteAsync() и в конечном итоге получает Grpc.Core.RpcException: 'Status(StatusCode="OK", Detail="")'
Вопрос: есть ли изящный способ заранее узнать, что вызов уже завершен, без ошибочных попыток записи?
Просматривая исходный код grpc-dotnet, мне удалось найти решение с помощью флага отражения AsyncClientStreamingCall.RequestStream.Call.ResponseFinished, но это выглядит даже хуже, чем обработка исключения с известным кодом состояния.
Псевдокод клиента:
private static async Task CallUploadStream(GrpcService.GrpcServiceClient client)
{
using var streamingCall = client.UploadStream();

// First call
await WriteAsync();

// Delay
await Task.Delay(TimeSpan.FromSeconds(1));

// Second call
await WriteAsync(); // Grpc.Core.RpcException: 'Status(StatusCode="OK", Detail="")'

await streamingCall.RequestStream.CompleteAsync();
await streamingCall;

return;

Task WriteAsync()
{
return streamingCall.RequestStream.WriteAsync(
new UploadStreamRequest
{
Bytes = ByteString.CopyFrom(new byte[1]),
}
);
}
}

Контракт Protobuf:
syntax = "proto3";
package grpc.debug.contract.v1;
option csharp_namespace = "GrpcDebug.Contract";
import "google/protobuf/empty.proto";

service GrpcService {
rpc UploadStream(stream UploadStreamRequest) returns (google.protobuf.Empty);
}

message UploadStreamRequest { bytes bytes = 1; }

Сервер, который немедленно возвращает ответ:
public class GrpcServiceV1 : GrpcService.GrpcServiceBase
{
public override Task UploadStream(IAsyncStreamReader requestStream,
ServerCallContext context)
{
return Task.FromResult(new Empty());
}
}


Подробнее здесь: https://stackoverflow.com/questions/791 ... ted-client

Вернуться в «C#»