是否可以使用WCF发现来公开使用命名管道的WCF端点?

时间:2011-08-15 18:08:23

标签: c# .net wcf network-programming

我有一个使用发现的应用程序,可以在同一台PC上本地部署,也可以从它所使用的服务远程部署。有没有办法通过WCF发现公开命名管道绑定?如果不是,我想我可以在发现服务后进行协商,以确定最合适的绑定。

1 个答案:

答案 0 :(得分:5)

是的,可以这样做。但由于地址将被列为“localhost”(net.pipe唯一可能的地址),因此您可能需要进行某种测试以验证该服务实际上是在与发现客户端相同的计算机上运行。

public class StackOverflow_7068743
{
    [ServiceContract]
    public interface ITest
    {
        [OperationContract]
        string Echo(string text);
    }
    public class Service : ITest
    {
        public string Echo(string text)
        {
            return text + " (via " + OperationContext.Current.IncomingMessageHeaders.To + ")";
        }
    }
    public static void Test()
    {
        string baseAddressHttp = "http://" + Environment.MachineName + ":8000/Service";
        string baseAddressPipe = "net.pipe://localhost/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddressHttp), new Uri(baseAddressPipe));
        host.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
        host.AddServiceEndpoint(new UdpDiscoveryEndpoint());
        host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "");
        host.AddServiceEndpoint(typeof(ITest), new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), "");
        host.Open();
        Console.WriteLine("Host opened");

        DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());
        FindResponse findResponse = discoveryClient.Find(new FindCriteria(typeof(ITest)));
        Console.WriteLine(findResponse.Endpoints.Count);

        EndpointAddress address = null;
        Binding binding = null;
        foreach (var endpoint in findResponse.Endpoints)
        {
            if (endpoint.Address.Uri.Scheme == Uri.UriSchemeHttp)
            {
                address = endpoint.Address;
                binding = new BasicHttpBinding();
            }
            else if (endpoint.Address.Uri.Scheme == Uri.UriSchemeNetPipe)
            {
                address = endpoint.Address;
                binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
                break; // this is the preferred
            }

            Console.WriteLine(endpoint.Address);
        }

        if (binding == null)
        {
            Console.WriteLine("No known bindings");
        }
        else
        {
            ChannelFactory<ITest> factory = new ChannelFactory<ITest>(binding, address);
            ITest proxy = factory.CreateChannel();
            Console.WriteLine(proxy.Echo("Hello"));
            ((IClientChannel)proxy).Close();
            factory.Close();
        }

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}