Я занят преобразованием службы WCF в gRPC. Один из методов — загрузка больших файлов посредством потоковой передачи. В настоящее время я использую .NET 6.0 для сервера и клиента.
Я следовал примеру, приведенному здесь.
Я продолжаю получать следующую ошибку:
System.IO.IOException: The request stream was aborted. ---> Microsoft.AspNetCore.Connections.ConnectionAbortedException: The HTTP/2 connection faulted.
Когда я запускаю сервер (докер-контейнер) и клиент (WPF) локально, то есть на своем компьютере, все работает. Но когда я перемещаю сервер в свой тестовый кластер Kubernetes на модуле, я получаю ошибку, описанную выше, с помощью трассировки стека.
System.IO.IOException: The request stream was aborted. ---> Microsoft.AspNetCore.Connections.ConnectionAbortedException: The HTTP/2 connection faulted. --- End of inner exception stack trace --- at System.IO.Pipelines.Pipe.GetReadResult(ReadResult& result) at System.IO.Pipelines.Pipe.GetReadAsyncResult() at System.IO.Pipelines.Pipe.DefaultPipeReader.GetResult(Int16 token) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2MessageBody.ReadAsync(CancellationToken cancellationToken) at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder1.StateMachineBox1.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token) at Grpc.AspNetCore.Server.Internal.PipeExtensions.ReadStreamMessageAsync[T](PipeReader input, HttpContextServerCallContext serverCallContext, Func2 десериализатор, CancellationToken cancelToken)
в System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder1.StateMachineBox1.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(токен Int16)
в Grpc.AspNetCore.Server.Internal.HttpContextStreamReader1.g__MoveNextAsync|13_0(ValueTask1 readStreamTask)
в Grpc.Core.AsyncStreamReaderExtensions.ReadAllAsyncCore[T](IAsyncStreamReader1 streamReader, CancellationToken cancellationToken)+MoveNext() at Grpc.Core.AsyncStreamReaderExtensions.ReadAllAsyncCore[T](IAsyncStreamReader1streamReader, CancellationToken cancelToken)+System.Threading.Tasks.Sources.IValueTaskSource.GetResult()
at KEY360.FacadeCore.Services.Key360Stream.UploadFile(IAsyncStreamReader)1 requestStream, ServerCallContext context) in KeyStream.cs:line 339 at KEY360.FacadeCore.Services.Key360Stream.UploadFile(IAsyncStreamReader1 requestStream, контекст ServerCallContext) в KeyStream.cs:строка 339
в KEY360.FacadeCore.Services.Key360Stream.UploadFile(IAsyncStreamReader1 requestStream, ServerCallContext context) in KeyStream.cs:line 404 at Grpc.Shared.Server.ClientStreamingServerMethodInvoker3.ResolvedInterceptorInvoker(IAsyncStreamReader1 requestStream, ServerCallContext resolvedContext) at Grpc.Shared.Server.ClientStreamingServerMethodInvoker3.ResolvedInterceptorInvoker(IAsyncStreamReader1 requestStream, ServerCallContext resolvedContext)
Вот мой код клиента и код сервера.
Клиент
// some other code here, but it just get the client and opens the file into a filestream
// and then calls the client UploadFileAsync
try
{
// Ensure the stream is positioned at the beginning
//
if (stream.CanSeek)
{
stream.Seek(0, SeekOrigin.Begin);
}
var streamInfo = new StreamInfo
{
AllowClientCaching = false,
Exception = null,
Length = stream.Length,
Message = GetRequestStringJSon(transaction),
NewDocumentID = newDocumentId,
FileName = Path.GetFileNameWithoutExtension(fileForUpload),
Success = true,
ServerCachingGUID = Guid.Empty.ToString(),
};
response = await service.UploadFileAsync(stream, streamInfo, JsonMetaData, ct);
}
catch (OperationCanceledException)
{
// Handle cancellation
Console.WriteLine("Upload canceled.");
}
catch (IOException ioEx)
{
// Handle I/O exceptions specifically
Console.WriteLine($"I/O Exception: {ioEx.Message}");
}
catch (Exception ex)
{
// Handle all other exceptions
Console.WriteLine($"Exception: {ex.Message}");
}
При вызове UploadFileAsync срабатывает перехват в строке перехвата (Exception ex).
public async Task UploadFileAsync(Stream data, StreamInfo info , Metadata metadata, CancellationToken? ct = null)
{
using (var call = _client.UploadFile(metadata))
{
int bufferSize = 1024 * 32; //32kb
var buffer = new byte[bufferSize];
int size = 0;
int total;
bool fileRead = false;
var chk = 1;
int chunkTotal = int.Parse((data.Length / bufferSize).ToString());
if (data.Length % bufferSize > 0)
chunkTotal++;
while (true)
{
total = await data.ReadAsync(buffer);
if (total == 0) break;
fileRead = true;
await call.RequestStream.WriteAsync(new PutRequest
{
Data = Google.Protobuf.ByteString.CopyFrom(buffer[0..total]),
Offset = size,
Info = new Protos.StreamInfo
{
AllowClientCaching = info.AllowClientCaching,
Exception = null,
FileName = info.FileName,
Length = info.Length,
Message = info.Message,
NewDocumentID = info.NewDocumentID,
ServerCachingGUID = info.ServerCachingGUID,
Success = info.Success
}
}, ct.GetValueOrDefault());
if (ct != null && ct.Value.IsCancellationRequested)
{
break;
ct.Value.ThrowIfCancellationRequested();
}
size += total;
chk++;
}
if (!fileRead)
{
await call.RequestStream.WriteAsync(new PutRequest
{
Offset = 0,
Info = new Protos.StreamInfo
{
AllowClientCaching = info.AllowClientCaching,
Exception = null,
FileName = info.FileName,
Length = info.Length,
Message = info.Message,
NewDocumentID = info.NewDocumentID,
ServerCachingGUID = info.ServerCachingGUID,
Success = info.Success
}
});
}
await call.RequestStream.CompleteAsync();
var done = await call.ResponseAsync;
if (done.Success) // completed
{
return new UploadResponse { Success = true, DocumentID = done.DocumentID, Exception = null };
}
else
return new UploadResponse { Success = false, DocumentID = done.DocumentID, Exception = done.Exception };
}
}
Код сервера выглядит следующим образом:
public override async Task UploadFile(IAsyncStreamReader requestStream, ServerCallContext context)
{
_serviceContract.Context = context;
try
{
var cts = new CancellationTokenSource(TimeSpan.FromMinutes(10));
var token = cts.Token;
if (context?.CancellationToken != null)
token = _serviceContract.Context.CancellationToken;
Facade.UploadStreamInfo uploadStream = null;
var fileName = Path.GetTempFileName() + ".upload";
await using var file = File.Create(fileName);//, FileMode.Create);
// THE ERROR HAPPENS HERE, ReadAllAsync, according to the stacktrace.
await foreach(var data in requestStream.ReadAllAsync(cancellationToken:token))
{
try
{
if (data.Data.Length > 0)
{
//file.Position = file.Length;
await file.WriteAsync(data.Data.ToByteArray());//, 0, bufferSize);
}
} catch (System.Exception ex) // this is not triggered, just some debug code.
{
await file.FlushAsync(token);
file.Close();
File.Delete(fileName);
throw new RpcException(Status.DefaultCancelled, $"WriteError on Server with error. {ex.Message}");
}
if (uploadStream == null && requestStream.Current != null)
{
uploadStream = new Facade.UploadStreamInfo
{
AllowClientCaching = requestStream.Current.Info.AllowClientCaching,
ByteStream = null,
FileName = requestStream.Current.Info.FileName,
NewDocumentID = requestStream.Current.Info.NewDocumentID,
Message = requestStream.Current.Info.Message,
Length = requestStream.Current.Info.Length,
ServerCachingGUID = requestStream.Current.Info.ServerCachingGUID,
Success = requestStream.Current.Info.Success
};
}
}
await file.FlushAsync(token);
file.Close();
// some code removed here....
// this code just move the uploaded file to the correct location, but it never gets here.
} catch (System.Exception ex)
{
//throw;
return new UploadResponse { DocumentID = -1, Success = false, Exception = new Protos.Exception { Exceptiontree = ex.InnerException?.Message, Message = ex.Message, Type = ExceptionType.Error, Stacktrace = ex.StackTrace } };
}
return new UploadResponse { DocumentID = -1, Success = false, Exception = new Protos.Exception { Message = "UploadFile failed due to unknown reason?", Type = ExceptionType.Validation } };
}
Подробнее здесь: https://stackoverflow.com/questions/790 ... as-aborted
Ошибка dotnet gRPC: поток запросов был прерван ⇐ C#
Место общения программистов C#
-
Anonymous
1727283690
Anonymous
Я занят преобразованием службы WCF в gRPC. Один из методов — загрузка больших файлов посредством потоковой передачи. В настоящее время я использую .NET 6.0 для сервера и клиента.
Я следовал примеру, приведенному здесь.
Я продолжаю получать следующую ошибку:
System.IO.IOException: The request stream was aborted. ---> Microsoft.AspNetCore.Connections.ConnectionAbortedException: The HTTP/2 connection faulted.
Когда я запускаю сервер (докер-контейнер) и клиент (WPF) локально, то есть на своем компьютере, все работает. Но когда я перемещаю сервер в свой тестовый кластер Kubernetes на модуле, я получаю ошибку, описанную выше, с помощью трассировки стека.
System.IO.IOException: The request stream was aborted. ---> Microsoft.AspNetCore.Connections.ConnectionAbortedException: The HTTP/2 connection faulted. --- End of inner exception stack trace --- at System.IO.Pipelines.Pipe.GetReadResult(ReadResult& result) at System.IO.Pipelines.Pipe.GetReadAsyncResult() at System.IO.Pipelines.Pipe.DefaultPipeReader.GetResult(Int16 token) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2MessageBody.ReadAsync(CancellationToken cancellationToken) at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder1.StateMachineBox1.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token) at Grpc.AspNetCore.Server.Internal.PipeExtensions.ReadStreamMessageAsync[T](PipeReader input, HttpContextServerCallContext serverCallContext, Func2 десериализатор, CancellationToken cancelToken)
в System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder1.StateMachineBox1.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(токен Int16)
в Grpc.AspNetCore.Server.Internal.HttpContextStreamReader1.g__MoveNextAsync|13_0(ValueTask1 readStreamTask)
в Grpc.Core.AsyncStreamReaderExtensions.ReadAllAsyncCore[T](IAsyncStreamReader1 streamReader, CancellationToken cancellationToken)+MoveNext() at Grpc.Core.AsyncStreamReaderExtensions.ReadAllAsyncCore[T](IAsyncStreamReader1streamReader, CancellationToken cancelToken)+System.Threading.Tasks.Sources.IValueTaskSource.GetResult()
at KEY360.FacadeCore.Services.Key360Stream.UploadFile(IAsyncStreamReader)1 requestStream, ServerCallContext context) in KeyStream.cs:line 339 at KEY360.FacadeCore.Services.Key360Stream.UploadFile(IAsyncStreamReader1 requestStream, контекст ServerCallContext) в KeyStream.cs:строка 339
в KEY360.FacadeCore.Services.Key360Stream.UploadFile(IAsyncStreamReader1 requestStream, ServerCallContext context) in KeyStream.cs:line 404 at Grpc.Shared.Server.ClientStreamingServerMethodInvoker3.ResolvedInterceptorInvoker(IAsyncStreamReader1 requestStream, ServerCallContext resolvedContext) at Grpc.Shared.Server.ClientStreamingServerMethodInvoker3.ResolvedInterceptorInvoker(IAsyncStreamReader1 requestStream, ServerCallContext resolvedContext)
Вот мой код клиента и код сервера.
Клиент
// some other code here, but it just get the client and opens the file into a filestream
// and then calls the client UploadFileAsync
try
{
// Ensure the stream is positioned at the beginning
//
if (stream.CanSeek)
{
stream.Seek(0, SeekOrigin.Begin);
}
var streamInfo = new StreamInfo
{
AllowClientCaching = false,
Exception = null,
Length = stream.Length,
Message = GetRequestStringJSon(transaction),
NewDocumentID = newDocumentId,
FileName = Path.GetFileNameWithoutExtension(fileForUpload),
Success = true,
ServerCachingGUID = Guid.Empty.ToString(),
};
response = await service.UploadFileAsync(stream, streamInfo, JsonMetaData, ct);
}
catch (OperationCanceledException)
{
// Handle cancellation
Console.WriteLine("Upload canceled.");
}
catch (IOException ioEx)
{
// Handle I/O exceptions specifically
Console.WriteLine($"I/O Exception: {ioEx.Message}");
}
catch (Exception ex)
{
// Handle all other exceptions
Console.WriteLine($"Exception: {ex.Message}");
}
При вызове UploadFileAsync срабатывает перехват в строке перехвата (Exception ex).
public async Task UploadFileAsync(Stream data, StreamInfo info , Metadata metadata, CancellationToken? ct = null)
{
using (var call = _client.UploadFile(metadata))
{
int bufferSize = 1024 * 32; //32kb
var buffer = new byte[bufferSize];
int size = 0;
int total;
bool fileRead = false;
var chk = 1;
int chunkTotal = int.Parse((data.Length / bufferSize).ToString());
if (data.Length % bufferSize > 0)
chunkTotal++;
while (true)
{
total = await data.ReadAsync(buffer);
if (total == 0) break;
fileRead = true;
await call.RequestStream.WriteAsync(new PutRequest
{
Data = Google.Protobuf.ByteString.CopyFrom(buffer[0..total]),
Offset = size,
Info = new Protos.StreamInfo
{
AllowClientCaching = info.AllowClientCaching,
Exception = null,
FileName = info.FileName,
Length = info.Length,
Message = info.Message,
NewDocumentID = info.NewDocumentID,
ServerCachingGUID = info.ServerCachingGUID,
Success = info.Success
}
}, ct.GetValueOrDefault());
if (ct != null && ct.Value.IsCancellationRequested)
{
break;
ct.Value.ThrowIfCancellationRequested();
}
size += total;
chk++;
}
if (!fileRead)
{
await call.RequestStream.WriteAsync(new PutRequest
{
Offset = 0,
Info = new Protos.StreamInfo
{
AllowClientCaching = info.AllowClientCaching,
Exception = null,
FileName = info.FileName,
Length = info.Length,
Message = info.Message,
NewDocumentID = info.NewDocumentID,
ServerCachingGUID = info.ServerCachingGUID,
Success = info.Success
}
});
}
await call.RequestStream.CompleteAsync();
var done = await call.ResponseAsync;
if (done.Success) // completed
{
return new UploadResponse { Success = true, DocumentID = done.DocumentID, Exception = null };
}
else
return new UploadResponse { Success = false, DocumentID = done.DocumentID, Exception = done.Exception };
}
}
Код сервера выглядит следующим образом:
public override async Task UploadFile(IAsyncStreamReader requestStream, ServerCallContext context)
{
_serviceContract.Context = context;
try
{
var cts = new CancellationTokenSource(TimeSpan.FromMinutes(10));
var token = cts.Token;
if (context?.CancellationToken != null)
token = _serviceContract.Context.CancellationToken;
Facade.UploadStreamInfo uploadStream = null;
var fileName = Path.GetTempFileName() + ".upload";
await using var file = File.Create(fileName);//, FileMode.Create);
// THE ERROR HAPPENS HERE, ReadAllAsync, according to the stacktrace.
await foreach(var data in requestStream.ReadAllAsync(cancellationToken:token))
{
try
{
if (data.Data.Length > 0)
{
//file.Position = file.Length;
await file.WriteAsync(data.Data.ToByteArray());//, 0, bufferSize);
}
} catch (System.Exception ex) // this is not triggered, just some debug code.
{
await file.FlushAsync(token);
file.Close();
File.Delete(fileName);
throw new RpcException(Status.DefaultCancelled, $"WriteError on Server with error. {ex.Message}");
}
if (uploadStream == null && requestStream.Current != null)
{
uploadStream = new Facade.UploadStreamInfo
{
AllowClientCaching = requestStream.Current.Info.AllowClientCaching,
ByteStream = null,
FileName = requestStream.Current.Info.FileName,
NewDocumentID = requestStream.Current.Info.NewDocumentID,
Message = requestStream.Current.Info.Message,
Length = requestStream.Current.Info.Length,
ServerCachingGUID = requestStream.Current.Info.ServerCachingGUID,
Success = requestStream.Current.Info.Success
};
}
}
await file.FlushAsync(token);
file.Close();
// some code removed here....
// this code just move the uploaded file to the correct location, but it never gets here.
} catch (System.Exception ex)
{
//throw;
return new UploadResponse { DocumentID = -1, Success = false, Exception = new Protos.Exception { Exceptiontree = ex.InnerException?.Message, Message = ex.Message, Type = ExceptionType.Error, Stacktrace = ex.StackTrace } };
}
return new UploadResponse { DocumentID = -1, Success = false, Exception = new Protos.Exception { Message = "UploadFile failed due to unknown reason?", Type = ExceptionType.Validation } };
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79024055/dotnet-grpc-error-the-request-stream-was-aborted[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия