我遇到了一个问题,可以通过以下方式复制(您需要 IIS8,因此必须在 Windows 8+ 或 Windows Server 2012 R2+ 上):
在 IIS 管理器中创建一个新网站(例如在端口 8881 上的 TestWs),指向一个新文件夹(例如 C:\temp\testws),然后在其中添加以下 Web.config 文件
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation targetFramework="4.5"/>
<httpRuntime targetFramework="4.5"/>
</system.web>
</configuration>
现在在同一文件夹中添加以下 WsHandler.ashx 文件
<%@ WebHandler Language="C#" Class="WsHandler" %>
using System;
using System.Threading;
using System.Web;
public class WsHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.AcceptWebSocketRequest(async webSocketContext =>
{
while (true)
{
await webSocketContext.WebSocket.ReceiveAsync(new ArraySegment<byte>(new byte[1024]), CancellationToken.None);
}
});
}
public bool IsReusable { get { return true; } }
}
然后从浏览器的开发人员工具栏中创建一个 Websocket,如下所示
var ws = new WebSocket("ws://localhost:8881/wshandler.ashx");
ws.onclose = function() { console.log('closed'); };
在任务管理器中,您将看到此应用程序有一个 w3wp.exe 进程,如果您终止它,客户端将引发 onclose 事件,并打印关闭的文本。
但是,如果您按照上述方式创建了一个websocket,然后进入IIS管理器并回收了应用程序池,则该websocket将不会被关闭,并且现在会有两个w3wp.exe进程。
关闭Web套接字ws.close();
或者刷新浏览器都会导致原来的w3wp.exe进程被关闭。
打开的 websocket 的存在似乎导致 IIS 无法正确回收应用程序池。
任何人都可以弄清楚要更改我的代码中的哪些内容或要更改 IIS 中的哪些内容才能使其正常工作吗?
最佳答案
据我所知,当 WebSocket 打开时,IIS 不会拆除应用程序域,因此您会看到这种行为。
我能建议的最好的办法是你做一些跨进程信号来强制旧实例关闭。您可以通过EventWaitHandle来实现这一点:
创建一个名为 EventWaitHandle在您的网络应用程序中,并在启动时发出信号。
在单独的线程上,等待等待句柄
收到信号后,请调用 HostingEnvironment.InitiateShutdown强制关闭任何正在运行的旧实例。
关于asp.net - 当存在打开的 ASP.NET 4.5 Websocket 时,IIS 应用程序池无法回收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27397484/