本文介绍了在WCF自托管中首次失败时,ServiceHost再次使用新的ServiceHost实例再次无法Open()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的症状与本帖子

我想知道这是否是

我的代码与Dave的代码略有不同,而他的ServiceHost实例(名为WebService)在Start()方法之外。我的ServiceHost实例(命名为host)在内部声明。调试时,我检查主机描述中端点的地址已更改为正确的IP。但是,Open()仍会使用旧的错误IP地址引发异常。

My code is slightly different from Dave's whereas his ServiceHost instance (named WebService) is outside of Start() method. My ServiceHost instance (named host) is declared inside. When debugging, I check in Host Description that the address of endpoints has changed to the correct IP. However, the Open() still throws an exception with the old wrong IP address.

    private bool InitHost(PtiType type, string serverIp, int portNumber)
    {
        if (!HostDictionary.ContainsKey(type))
        {
            Uri addressBase = new Uri(String.Format("net.tcp://{0}:{1}/CommunicationService/{2}", serverIp, portNumber.ToString(), type.ToString()));
            var service = new PtiCommunicationService(type);

            service.ClientConnected += service_ClientConnected;
            service.ClientBroadcasted += service_ClientBroadcasted;
            service.ClientSentTo += service_ClientSentTo;
            service.ClientDisconnected += service_ClientDisconnected;

            var host = new ServiceHost(service, addressBase);

            //For publishing metadata only
            //Define Metadata endPoint, So we can publish information about the service
            ServiceMetadataBehavior mBehave = new ServiceMetadataBehavior();
            host.Description.Behaviors.Add(mBehave);

            //Enable debug info in fault
            ((ServiceDebugBehavior)host.Description.Behaviors[typeof(ServiceDebugBehavior)]).IncludeExceptionDetailInFaults=true;

            host.AddServiceEndpoint(typeof(IPtiCommunication), new NetTcpBinding(SecurityMode.None), "");
            host.AddServiceEndpoint(typeof(IMetadataExchange),
                MetadataExchangeBindings.CreateMexTcpBinding(),
                "mex");

            try
            {
                host.Open();

                //Add host to dictionary to keep track
                HostDictionary.Add(type, host);

                LogList.Add(String.Format("{0}\tThe service {1} at {2} is ready", DateTime.Now.ToLongTimeString(), service.ServiceType.ToString(), serverIp));

                string hostInfo = String.Format("{0}\tHost information:\n", DateTime.Now.ToLongTimeString());

                hostInfo += "Enpoints details:\n";
                foreach (var endpt in host.Description.Endpoints)
                {
                    hostInfo += String.Format("\t Name:\t\t{0}\n", endpt.Name);
                    hostInfo += String.Format("\t Logical address:\t{0}\n", endpt.Address);
                    hostInfo += String.Format("\t Physical address:\t{0}\n", endpt.ListenUri);
                    hostInfo += String.Format("\t Binding:\t\t{0}\n", endpt.Binding);
                    hostInfo += String.Format("\t Contract:\t{0}\n\n", endpt.Contract.ContractType.Name);
                }
                LogList.Add(hostInfo);
            }
            catch (Exception e)
            {
                host.Abort();
                host = null;
                LogList.Add(String.Format("{0}\t{1}", DateTime.Now.ToLongTimeString(), e.Message));
            }
            return true;
        }
        return false;
    }

这是我的PtiCommunicationService服务行为

Here is my ServiceBehavior for PtiCommunicationService

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
 ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]

和接口的ServiceContract

and ServiceContract for the interface

[ServiceContract(CallbackContract = typeof(IPtiCommunicationCallback), SessionMode = SessionMode.Required)]

应用程序中没有其他配置。配置。

There is no other configurations in app.config. All are in the code.

谢谢

更新:

我发现我们两个人都对ServiceHost构造函数(对象,Uri [])使用相同的重载,从而使Web服务成为一个单例。

I've discovered that both of us use the same overload for ServiceHost Constructor (Object, Uri[]) which make a singleton of web service.

何时我们使用相同的单例创建新的服务主机,因此即使主机已中止,更改端点地址也不会受到影响,因为服务实例仍然存在。

When we create new Service Host with the same singleton, somehow changing endpoint address doesn't take into affect because the instance of the service is still there even though the host has been aborted.

创建新主机时,是否有任何解决方案可以清理该单例?

Is there any solution to clean up that singleton when we create new host?

到目前为止,我一直怀疑,如果我错了,请纠正我。

That's my suspicion so far, please correct me if I'm wrong.

推荐答案

显然,WCF缓存了一些套接字信息。我发现的最佳解决方法是Ivan在中给出的。在尝试调用host.Open()之前,请检查是否可以打开连接。

Apparently WCF caches some socket information. The best workaround I have found was given by Ivan here https://stackoverflow.com/a/6839265/955400 . You check if you can open the connection before attempting to call host.Open().

这篇关于在WCF自托管中首次失败时,ServiceHost再次使用新的ServiceHost实例再次无法Open()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-19 15:42