簡體   English   中英

配置和啟動 WCF 服務的問題

[英]Problem with configuring and starting WCF service

我在配置和啟動 WCF 服務時遇到問題。 在我的應用程序中有一個啟動服務的方法。 像這樣的東西

void Start(string protocol, string address, string port)
{
    host = new ServiceHost(_myService,
        new Uri(String.Format("{0}://{1}{2}/Sample", protocol, address, port)));
    //...Some configuration (bindings, behaviors, etc.)
    host.Open();
}

讓我的電腦有一個 IP 192.168.0.1。 當我傳遞值為“192.168.0.2”的“地址”參數時,發生錯誤

"A TCP error (10049: The requested address is not valid in its context.)
 occurred while listening on IP Endpoint=192.168.0.2:1234"

沒錯,因為它不是我的 IP。 但在那之后,如果我傳遞正確的值(我的真實 IP),我會收到關於 IP 192.168.0.2 的相同錯誤。 所以我無法在不重新啟動應用程序的情況下重新配置和重新啟動服務器。

為什么會這樣? 我怎樣才能避免這種行為?

從您的問題中我看不到您如何添加正確的端點,但我懷疑您正在嘗試修改端點地址。 使用 WCF 服務,調用后無法更改端點地址

host.Open();

因為此時服務已啟動(如果您沒有錯誤)並接受來自指定地址和端口號的客戶端的請求。

如果您希望在新地址托管服務,則需要使用正確的端點地址(並處置舊地址)創建新的 ServiceHost object。

編輯:

在玩弄了您發布的示例解決方案之后,我找到了該問題的解決方案。 我認為出了點問題,因為您在兩次嘗試中都使用了相同的端口號(在我下載的示例解決方案中,您沒有指定這個,所以端口默認為 808)。 如果您按如下方式更改代碼以在第二次嘗試的基地址中指定不同的端口號,您遇到的錯誤就會消失:

 try
        {
            var host2 = CreateServiceHost("localhost:5432", serviceImpl);

            Console.WriteLine("#2, config: " + host2.BaseAddresses.First().ToString());

            host2.Open();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }

WCF 本身下面似乎有一些錯誤,可能在套接字級別,在第一個錯誤 IP 出現錯誤后,端口仍然不可用。

我快速搜索了一下, 發現這篇文章有人在關閉套接字后重用端口時遇到延遲。 如果您總是需要使用相同的端口號,也許您可以等待一段時間讓端口再次空閑,然后再嘗試再次創建服務主機。

看起來 WCF 在 class ExclusiveTCPTransportManager 中緩存了一個套接字 object。

這對我來說似乎是一個很好的解決方案:

public static class WCFBugWorkaround
{
    public static bool IsConnectionPossible(this ServiceHost host)
    {
        try
        {
            foreach (var baseAddress in host.BaseAddresses)
            {
                IPAddress[] ipAddresses = Dns.GetHostAddresses(baseAddress.DnsSafeHost);
                IPAddress ipAddr = ipAddresses.Where(e => e.AddressFamily == AddressFamily.InterNetwork).FirstOrDefault();

                if (ipAddr == null)
                {
                    return false;
                }

                using (Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
                {
                    System.Net.IPEndPoint localEP = new IPEndPoint(ipAddr, baseAddress.Port);
                    s.Bind(localEP);
                }
            }
        }
        catch (Exception ex)
        {
            return false;
        }

        return true;
    }
}

ServiceHost host = ...;

...

if (host.IsConnectionPossible())
{
    host.Open();
}

感謝 Francheska 向我展示了正確的方向:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM