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

本文关键字:WCF 管道 端点 发现 可以使 是否 | 更新日期: 2023-09-27 18:05:33

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

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

是的,这是可能的。但是,由于地址将被列为"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();
    }
}