IIS 回收应用程序池时如何保持 Blazor 服务器连接处于活动状态

Posted

技术标签:

【中文标题】IIS 回收应用程序池时如何保持 Blazor 服务器连接处于活动状态【英文标题】:How to keep Blazor Server connection active when IIS is recycling the application pool 【发布时间】:2021-03-12 09:32:53 【问题描述】:

我正在为我的客户构建 Blazor Server Intranet 应用程序。其中一项要求是他们可以无限期地保持登录状态。如果他们在周五下午开始输入一些数据,他们应该能够在周一早上返回并继续工作而不会中断。

我发现客户端每天大约断开一次与服务器的连接。发生这种情况时,我会看到可怕的 Blazor 错误“重新连接失败。如果无法重新连接,请尝试重新加载页面。”。如果我单击重新加载链接,它会立即重新连接到我的服务器,但任何正在进行的工作都会丢失。

我找到了根本原因:默认情况下,IIS 每 29 小时回收一次应用程序池。发生这种情况时,Blazor SignalR 连接会中断,因此在浏览器中运行的代码会超时并断开连接。

我可以通过完全禁用应用程序池回收来解决此问题。到目前为止,看起来效果很好(我可以在过去 3 天内保持连接)。但我担心从长远来看这可能不安全,因为应用程序池回收有助于处理内存泄漏、碎片等问题。

所以,我的问题是:是否可以配置 IIS,以便我可以回收应用程序池并在回收期间保持我的 blazor 服务器连接可用?

【问题讨论】:

您要么禁用 IIS 应用程序池回收,要么接受以这种方式重置连接的事实。这也是微软开发 Blazor WebAssembly 的原因,它不会以同样的方式中断。 这能回答你的问题吗? SignalR connection handling on app pool recycle 嗨,shanabus,感谢您的链接。它确实提供了更多信息,但似乎并没有完全解决这个问题。当应用程序池回收时,我似乎将丢失保存在服务器上的所有应用程序数据。除非我可以在回收之前将其保存到磁盘或数据库中,然后在新池启动时重新加载。 如果你想在两次刷新之间保留状态(这似乎真的归结为),我建议使用会话存储。当您加载页面或组件时,请检查会话存储中是否存在适当的数据并从中初始化您的对象和变量。您必须确保根据需要清除会话存储。 嗨 Lex,实际上这里有两个问题:1)我不希望我的用户正在进行的工作在应用程序回收期间丢失,2)我想保留一些用户数据。在我的应用程序中,我将敏感的用户数据存储在服务器端,并且不想将其放入浏览器端会话存储中。 【参考方案1】:

当您回收应用程序池时,HTTP.SYS 在内核模式下保持客户端连接,而用户模式工作进程回收。进程回收后,HTTP.SYS 透明地将新请求路由到新的工作进程。因此,客户端永远不会“丢失所有连接”到服务器 - TCP 连接永远不会丢失 - 并且永远不会注意到进程循环。

我相信您的问题在于您的应用程序池中运行的应用程序在进程中存储状态,例如用户是否登录。每次流程回收时,该状态都会自动丢失……这是设计使然,因为这是流程回收所完成的。结果,您的用户“失去所有连接”并且“必须重新登录到他们的应用程序”以重新建立丢失的状态。解决此问题的唯一方法是让您的应用程序将其状态存储在 IIS 工作进程之外,以便回收利用。

以下博客文章详细介绍了正在发生的事情:

https://docs.microsoft.com/en-us/archive/blogs/david.wang/why-do-i-lose-asp-session-state-on-iis6

【讨论】:

您好,丁,感谢您的建议。在 Blazor 中,没有会话这样的概念。 Blazor 使用 SignalR 协议,而不是 HTTP。我已经创建了自己的会话概念,当应用程序 bool 回收时,我确实会丢失该数据。但除此之外,浏览器端还会显示错误消息“重新连接失败。如果无法重新连接,请尝试重新加载页面”,因为 SignalR 在服务器关闭时一直尝试发送数据。 更多服务器断线场景可以参考这个链接:docs.microsoft.com/en-us/aspnet/signalr/overview/… 丁,谢谢你的链接。这是有用的信息 嗨丁,我确实赞成您的评论,因为我认为它很有用。但你并没有真正回答我的问题。实际上,Lex Li 似乎确实为我的具体问题提供了最现实的答案:我想做的事做不到! @JasonD 2021 年你找到解决方案了吗?仍然不确定我是否应该在我的项目中使用 blazor :(

以上是关于IIS 回收应用程序池时如何保持 Blazor 服务器连接处于活动状态的主要内容,如果未能解决你的问题,请参考以下文章

WCF 调用的 IIS 请求限制回收

IIS 应用程序池 - 停止/启动与回收

如何使用默认网站在 iis 中配置 blazor 应用程序?

在哪里可以找到有关如何将 Blazor 应用部署到在 Windows Server 2019 上运行的 IIS10 的具体详细信息

Blazor WASM - IIS 上的独立部署

如何使用 IIS 从 Blazor 服务器获取 WindowsIdentity.RunImpersonated(token, action) 的 HttpContext(或 AccessToken)