我正在编写一个完全堆栈的应用程序,用于节日时监视酒吧的库存(例如,他们有多少瓶杜松子酒)。它允许创建一个传输请求,以便将更多的东西送到特定的栏中,并查找这些请求。当连接速度慢到导致超时时(通过我在1KB/s的测试中上传/下载油门,它花费了大约10秒),但仍然将数据发送到API时,问题就出现了。
我处理将数据写入数据库的方法如下所示:
public IActionResult WriteStorageTransfer([FromBody] StorageTransfer transfer)
{
Console.WriteLine("Started the execution of method");
var transferId = database.CreateNewDoc(transfer);
foreach (var item in transfer.items)
{
var sql = @$"insert into sklpohyb(idsklkarta, iddoc, datum, pohyb, typp, cenamj, idakce, idbar, idpackage, isinbaseunit)
values ({item.id}, {transferId}, current_timestamp, {packMj}, {transfer.typ}, {item.prodejnicena}, {transfer.idakce}, {transfer.idbar}, case when {pack.idbaleni} = -1 then NULL else {pack.idbaleni} end, {pack.isinbaseunit})";
database.ExecuteQueryAsTransmitter(sql);
}
return Ok(transferId); // transferId is then used by frontend to display the created transfer request.
}
这一切都很好,但前端似乎将数据发送到API,API对其进行处理并将其写入数据库,但在HttpRequest
上发生超时,使方法崩溃,因此永远不会将HttpResponse
返回到前端(或返回代码0:“未知错误”)。
API引发的异常:
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
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 Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2MessageBody.ReadAsync(CancellationToken cancellationToken)
at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestStream.ReadAsyncInternal(Memory`1 destination, CancellationToken cancellationToken)
at System.Text.Json.JsonSerializer.ReadFromStreamAsync(Stream utf8Json, ReadBufferState bufferState, CancellationToken cancellationToken)
at System.Text.Json.JsonSerializer.ReadAllAsync[TValue](Stream utf8Json, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinder.BindModelAsync(ModelBindingContext bindingContext)
at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object valu
e, Object container)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext()
--- End of stack trace from previous location ---
发送给API的JSON的大小通常是10 KB,不像100 KB那样严重,所以我认为大小不是问题所在
这样会使前端挂起,用户可能会再次单击按钮,可能会将多个副本写入数据库,因为他不知道发票是否已被处理,或者应用程序中是否有错误。
有趣的是,Console.Write("Started execution of the method")
不会被触发,因为我没有在控制台窗口中看到它,但是数据在手动检查之后会被写入数据库。
如果我能通知用户在创建传输请求时出了问题,并且阻止了在数据库中创建它,那就太好了。我尝试在try catch
上使用IOException块
非常感谢,在这一点上什么都行。
发布于 2022-08-19 11:29:51
当连接速度慢到导致超时,但仍然将数据发送到API时,就会出现问题。
回到图纸(或时间给我们更多的细节)。如果您的POS应用程序(我认为这是)想要向后端报告销售情况,用户为什么要等待?为什么用户能够报告一次销售两次?
相反,让客户机在本地生成一个唯一的事务ID,并将它们存储在本地存储中,并且(在每次出售之后,并且定期地,但最重要的是:在后台)让客户机尝试将它们的事务同步到服务器。然后,服务器可以拒绝重复的交易,这样它就不会记录相同的交易两次,并且您的应用程序可以处理期间没有或不稳定的互联网访问。
至于您的错误:超时可能是一分钟左右,这对于这个用例来说可能太长了。如果客户端没有HTTP响应,它最终会抛出一个异常,但是您想让您的酒吧人员在POS上等待一分钟吗?他们会称它为POS。
https://stackoverflow.com/questions/73415663
复制相似问题