IIS App Pool cannot recycle when there is an open ASP.NET 4.5 Websocket

前端 未结 3 2302
春和景丽
春和景丽 2021-02-15 15:18

I have run into an issue which can be replicated in the following way (you need IIS8 so must be on Windows 8+ or Windows Server 2012 R2+):

Create a new website in IIS Ma

相关标签:
3条回答
  • 2021-02-15 15:42

    Try setting "Shutdown Time Limit" to 1 second (App Pool > Advanced Settings > Process Model) [PS: I don't have IIS8. I'm checking the properties in IIS7.]

    This property defines the time given to worker process to finish processing requests and shutdown. If the worker process exceeds the shutdown time limit, it is terminated.

    I can see default value in IIS7 is 90 seconds. If that's the same value in IIS8 too, then it might be giving that much time to earlier worker process to finish it's work. After 90 seconds (1.5 mins) it will terminate that process and your web socket will get closed. If you change it to 1 second it will terminate the earlier worker process will get terminated almost instantly (as soon as you recycle app pool) and you will get the expected behavior.

    0 讨论(0)
  • 2021-02-15 15:44

    As I had the same problem, here's the solution I figured out:

    In your IHttpHandler you should have an static object which inherits IStopListeningRegisteredObject. Then use HostingEnvironment.RegisterObject(this) to get notified (via StopListening) when the Application Pool is recyled.

    You'll also need a CancellationTokenSource (static, too), which you'll hand over in ReceiveAsync. In StopListening() you can then use Cancel() of the CancellationTokenSource to end the await. Then catch the OperationCanceledException and call Abort() on the socket.

    Don't forget the Dispose() after the Cancel() or the App-Pool will still wait.

    0 讨论(0)
  • 2021-02-15 16:01

    As far as I know, while a WebSocket is open, IIS won't tear down the app domain, so you see this behaviour exhibited.

    The best I can suggest is that you do some cross process signalling to force the old instance to shutdown. You could achieve this with an EventWaitHandle:

    1. Create a named EventWaitHandle in your web application, and signal it at startup.

    2. On a separate thread, wait on the wait handle

    3. When it is signalled, call HostingEnvironment.InitiateShutdown to force any running old instance to shutdown.

    0 讨论(0)
提交回复
热议问题