asp.net - 当存在打开的 ASP.NET 4.5 Websocket 时,IIS 应用程序池无法回收

标签 asp.net iis websocket

我遇到了一个问题,可以通过以下方式复制(您需要 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来实现这一点:

  1. 创建一个名为 EventWaitHandle在您的网络应用程序中,并在启动时发出信号。

  2. 在单独的线程上,等待等待句柄

  3. 收到信号后,请调用 HostingEnvironment.InitiateShutdown强制关闭任何正在运行的旧实例。

关于asp.net - 当存在打开的 ASP.NET 4.5 Websocket 时,IIS 应用程序池无法回收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27397484/

相关文章:

asp.net - 与 aspnet_regiis -ga <用户名> 相反

javascript - websocket (NODEJS) 的僵尸 session ?

javascript - 通过 websockets 使用 javascript 传输文件

.net - 覆盖 AuthorizeAttribute.AuthorizeCore 时为 "cannot set status after HTTP headers"

c# - 具有多个参数的 ASP.NET Web 服务 HttpPut

mysql - 如何使用mysql查询发送带附件的电子邮件

c - 使用recv()接收消息 block

javascript - 如何让 window.showmodaldialog 在 chrome 37 中工作?

asp.net - 在 ASP.NET Core 应用程序中使用标准 Active Directory?

asp.net - 在 IIS 7.5 上的同一端口上运行两个网站?