繁体   English   中英

回收 AppPool 时,通常只允许每个套接字地址(协议.网络地址/端口)使用一次

[英]Only one usage of each socket address (protocol/network address/port) is normally permitted when AppPool is recycled

我有一个 .net Core 应用程序托管在 IIS 上。该应用程序通过将包装器 class 添加为HostedService来初始化WebSocketServer 托管服务在其 StartAsync() 上执行Start()方法,在其StopAsync ()方法上执行Destroy () 方法。 每当相关应用程序池被回收时的问题——出现标题中的错误(“Only one usage of each socket address (protocol.network address/port) is normally permitted”)。 发生这种情况是因为有一个新的工作进程启动并尝试在关闭当前工作进程之前使用套接字的端口,该进程仍然使用具有相同端口的套接字。 我正在尝试以编程方式或通过配置找到避免这种情况的方法。 这是我的 HostedService 代码:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;
using System.Linq;
using System.Net.WebSockets;
using WebSocketSharp.Server;

namespace XXXX
{
    public class WebsocketServerWrapper
    {
        // Thats an websocket server , he will host our service as web socket service.
        private static WebSocketServer wss;
        private static readonly object LockObject = new object();

        public static IConfiguration Config { get; set; }

        public static bool IsCreated()
        {
            return wss != null;
        }

        public static bool HasChannels()
        {
            if(IsCreated())
            {
                return wss.WebSocketServices.Paths.Any();
            }

            return false;
        }

        public static bool IsListening()
        {
            if (wss != null)
            {
                return wss.IsListening;
            }

            return false;
        }

        public static void AddChannel(string channel)
        {
            if (wss.WebSocketServices.Paths.Any((path) => path == channel) == false)
            {
                    wss.AddWebSocketService(channel,() => new <class that treats the socket behaviour itself>(Config));
            }
        }

        public static bool Start()
        {
            wss.Start();

            if (IsListening())
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public static bool Destroy()
        {
             var isDestroyed = false;

            if(IsCreated())
            {
                removeWebSocketServices();
                wss.Stop();
                wss = null;
                isDestroyed = true;
            }

            return isDestroyed;
        }
        internal static void removeWebSocketServices()
        {
            var channels = wss?.WebSocketServices?.Paths?.ToList() ?? null;
            if (channels != null)
            {
                channels.ForEach(channel => { wss.RemoveWebSocketService(channel); channel = null; });
            }
        }

        public static bool CreateWSSServer()
        {
            bool isCreationSucceeded = false;

            if(!IsCreated())
            {
                lock(LockObject)
                {
                    try
                    {
                        var wssUrl = Config.GetValue<string>(<WebsocketServerUrl adress>);

                        wss = new WebSocketServer($"ws://{wssUrl}");
                        isCreationSucceeded = true;
                    }
                    catch (WebSocketException wse)
                    {
                        Debug.WriteLine(wse);
                        return isCreationSucceeded;
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine(e);
                        return isCreationSucceeded;
                    }
                }
            }

            isCreationSucceeded = true;

            return isCreationSucceeded;
        }

    }
}

我找到了该场景的解决方案(在问题中对其进行了编辑)-事实证明,服务器在“旧”工作进程关闭之前使用新工作进程启动的情况并不少见-应用程序中有一个参数Recycling => Disable Overlapped Recycle下的池 - 如果它设置为 true(默认情况下为 false),则只有在当前工作进程关闭后才会启动新的工作进程

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM