【问题标题】:HttpRequest not aborted (cancelled) on browser abort in ASP.NET Core MVC在 ASP.NET Core MVC 中浏览器中止时,HttpRequest 未中止(取消)
【发布时间】:2017-01-27 04:41:59
【问题描述】:

我编写了以下 MVC 控制器来测试取消功能:

class MyController : Controller
{
    [HttpGet("api/CancelTest")]
    async Task<IActionResult> Get()
    {
        await Task.Delay(1000);
        CancellationToken token = HttpContext.RequestAborted;
        bool cancelled = token.IsCancellationRequested;
        logger.LogDebug(cancelled.ToString());
        return Ok();
    }
}

说,我想取消请求,所以在上面的控制器操作中记录了值“true”。如果服务器实现 IHttpRequestLifetimeFeature,这可能是服务器端的。幸运的是,Kestrel 做到了,这可以通过以下方式完成:

var feature = (IHttpRequestLifetimeFeature) HttpContext.Features[typeof(IHttpRequestLifetimeFeature)];
feature.Abort();

但问题是我想在客户端取消请求。例如,在浏览器中。在 ASP.NET MVC/WebApi 的预核心版本中,如果浏览器中止请求,取消令牌将自动取消。示例:在 Chrome 中刷新页面几次。在 chrome 开发工具的 Network 标签中,您现在可以看到之前的(未完成的)请求被取消了。

事情是:在 Kestrel 上运行的 ASP.NET Core 中,我只能在日志中看到以下条目:

Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: 错误 -4081 ECANCELED 操作已取消

因此,来自浏览器的中止请求确实到达并由 Kestrel 网络服务器处理。但是,它不会影响控制器中 HttpContext 的 RequestAborted 属性,因为该方法仍会记录值“false”。

问题: 有没有办法中止/取消我的控制器的方法,以便将 HttpContext.RequestAborted 属性标记为已取消?

也许我可以制作一些订阅 Kestrel 的操作取消触发器并调用 IHttpRequestLifetimeFeature.Abort() 方法的东西?

更新: 我做了一些进一步的测试,似乎 HttpRequest IS 实际上已中止,但在取消实际发生之前似乎存在某种延迟。延迟不是时间因素,并且似乎直接来自 libuv(Kestrel 网络服务器建立在其之上的库)。我在https://github.com/aspnet/KestrelHttpServer/issues/1103上发布了更多信息

更多更新: 问题已移至另一个问题,因为前一个问题包含多个问题。 https://github.com/aspnet/KestrelHttpServer/issues/1139

【问题讨论】:

  • 我投票决定将此问题作为题外话结束,因为问题似乎现在已得到解决
  • @Set:没关系。它确实应该在 2.0 中修复。我不能自己结束这个问题,可以吗?
  • 如果您认为问题不再对其他用户有帮助,您可以删除问题,或者您可以发布自己的答案(稍后接受)并说这是 Kestrel 服务器实现中的错误已修复现在。
  • 当使用 IIS 作为 Kestrel github.com/aspnet/AspNetCoreModule/issues/38 的反向代理时,还有一个问题尚未解决(截至 2.1 版)。因此,即使原始问题已得到修复,这仍然是一个非常有用的问题。

标签: asp.net-core asp.net-core-mvc cancellation kestrel-http-server


【解决方案1】:

事实证明,简单地使用 HttpContext.RequestAborted 确实是正确的方法,但由于 Kestrel 中的一个错误(处理 FIN/RST 包的顺序),请求并没有在浏览器中止时中止。

这个错误最终应该在 Kestrel 2.0 中得到修复。

有关更多信息,请参阅我的问题中的更新。

【讨论】:

  • 谢谢。是的,你是对的。可能是 Kestrel 中存在错误。我尝试使用 HttpContext.RequestAborted 但仍然无法正常工作,因此我尝试不使用 IIS Express(请参阅 stackoverflow.com/questions/47153525/…)并且它成功了。
猜你喜欢
  • 2019-08-03
  • 1970-01-01
  • 1970-01-01
  • 2011-08-21
  • 2018-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多