WCF:在使用唯一的ListenUri和WCF发现时,To和via uri必须匹配错误

时间:2018-01-27 06:07:51

标签: c# wcf ws-discovery

我正在尝试创建一个使用httpBinding的WCF服务,我想要唯一的Listen Uri。客户端使用WCF发现来检测发现代理中的服务。操作合同的保护级别设置为无

我在客户端说错误并且通过uri必须是相同的:

控制台输出:

Finding ICalculatorService endpoints...

Found 1 ICalculatorService endpoint(s).

Invoking CalculatorService at http://localhost/ac5271c3-14ea-45b0-8519-ab1c20f6bdac/
Using the viaUri http://localhost/ac5271c3-14ea-45b0-8519-ab1c20f6bdac/b5bb79cc-84a1-44f5-a913-b8928b51232a


Unhandled Exception: System.ArgumentException: The binding specified requires that the to and via URIs must match because the Addressing Ver
sion is set to None. The to URI specified was 'http://localhost/ac5271c3-14ea-45b0-8519-ab1c20f6bdac/'. The via URI specified was 'http://lo
calhost/ac5271c3-14ea-45b0-8519-ab1c20f6bdac/b5bb79cc-84a1-44f5-a913-b8928b51232a'.
   at System.ServiceModel.Channels.HttpChannelFactory`1.ValidateCreateChannelParameters(EndpointAddress remoteAddress, Uri via)
   at System.ServiceModel.Channels.HttpChannelFactory`1.OnCreateChannelCore(EndpointAddress remoteAddress, Uri via)
   at System.ServiceModel.Channels.ChannelFactoryBase`1.InternalCreateChannel(EndpointAddress address, Uri via)
   at System.ServiceModel.Channels.ServiceChannelFactory.ServiceChannelFactoryOverRequest.CreateInnerChannelBinder(EndpointAddress to, Uri v
ia)

服务:

Uri baseAddress = new Uri("http://localhost/" + Guid.NewGuid().ToString() + "/");
ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress);

        try
        {
            ServiceEndpoint endpoint = serviceHost.AddServiceEndpoint(typeof(ICalculatorService), new BasicHttpBinding(), string.Empty);

            // Set the ListenUri mode to unique
            endpoint.ListenUriMode = ListenUriMode.Unique;

            // Make the service discoverable over UDP multicast
            serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
            serviceHost.AddServiceEndpoint(new UdpDiscoveryEndpoint());

            serviceHost.Open();

            Console.WriteLine("Calculator Service started at {0}", baseAddress);

            Console.ReadLine();
        }
        catch (CommunicationException e)
        {
            Console.WriteLine(e.Message);
        }

客户端:

 DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());

        Console.WriteLine("Finding ICalculatorService endpoints...");
        Console.WriteLine();

        FindCriteria findCriteria = new FindCriteria(typeof(ICalculatorService));
        findCriteria.Duration = TimeSpan.FromSeconds(5);

        // Find ICalculatorService endpoints            
        FindResponse findResponse = discoveryClient.Find(findCriteria);

        Console.WriteLine("Found {0} ICalculatorService endpoint(s).", findResponse.Endpoints.Count);
        Console.WriteLine();

        // Check to see if endpoints were found
        if (findResponse.Endpoints.Count > 0)
        {
            EndpointDiscoveryMetadata discoveredEndpoint = findResponse.Endpoints[0];

            // Check to see if the endpoint has a listenUri and if it differs from the Address URI
            if (discoveredEndpoint.ListenUris.Count > 0 && discoveredEndpoint.Address.Uri != discoveredEndpoint.ListenUris[0])
            {
                // Since the service is using a unique ListenUri, it needs to be invoked at the correct ListenUri 
                InvokeCalculatorService(discoveredEndpoint.Address, discoveredEndpoint.ListenUris[0]);
            }
            else
            {
                // Endpoint was found, however it doesn't have a unique ListenUri, hence invoke the service with only the Address URI
                InvokeCalculatorService(discoveredEndpoint.Address, null);
            }
        }

InvokeCalculatorService:

CalculatorServiceClient client = new CalculatorServiceClient(new BasicHttpBinding(), endpointAddress);
        Console.WriteLine("Invoking CalculatorService at {0}", endpointAddress.Uri);

    // if viaUri is not null then add the approprate ClientViaBehavior.
    if (viaUri != null)
    {
        client.Endpoint.Behaviors.Add(new ClientViaBehavior(viaUri));
        Console.WriteLine("Using the viaUri {0}", viaUri);
    }

    Console.WriteLine();

    double value1 = 100.00D;
    double value2 = 15.99D;

    // Call the Add service operation.
    double result = client.Add(value1, value2);
    Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);

请帮我解决上述错误

1 个答案:

答案 0 :(得分:1)

这可能与使用basicHttpBinding有关,basicHttpBinding不使用WS-addressing,因此没有To地址(参见https://social.msdn.microsoft.com/Forums/en-US/8386191c-8bd5-49c7-8816-ddb04cb419c0/basichttpbinding-separating-logical-and-physical-address?forum=wcf)。

如果您没有迫切要求使用WsHttpBinding,则可以尝试使用CalculatorServiceClient client = new CalculatorServiceClient(new WsHttpBinding(), endpointAddress);

class A
{
public:

    template<class T>
    A& A::operator=(const T& obj)
    {
        return *this;
    }
};