locked
WCF Discovery has the A and C of the A, B, Cs' - but what about the 'B' (Binding)

    Question

  • Sorry for the cross-post - I figured this question would be better suited to this forum.

    At least in beta-1, using discovery, the discovery reply would identify both the contract and address of a WCF endpoint - but not the Binding type - you had to already know this to talk to the service.
    Has this changed in beta2 so that one can be entirely ignorant of the binding settings until discovery locates the endpoint?
    If this hasnt been implemented - shouldnt it?

    Thanks
    Tuesday, December 08, 2009 10:31 PM

Answers

All replies

  • You probably want to look into the Dynamic Proxy feature. Take a look at this blog post:

    http://blogs.msdn.com/vipulmodi/archive/2006/11/16/dynamic-programming-with-wcf.aspx

    It explains to you how to communicate with a service by just providing its address. Contracts and bindings are obtained at runtime. Also, this feature allows you to postpone the client proxy generation to the runtime.

    You can download the Dynamic Proxy sample from that blog post. In post-.NET 4, we will include this feature in the framework.

    Hope this helps.
    Wednesday, December 09, 2009 12:10 AM
  • Thanks Amadeo,

    This isnt quite what I am after however.
    I do actually know what the contract will be - so I am able to use the ChannelFactory<T> to communicate with it.
    I dont see how this 'dynamic proxy' can possibly infer all the binding information required.. I assume it just looks at the URI scheme (net.tcp, http) to create the correct binding type.
    But it cannot infer all options (such as the security mode) - this would need to be 'advertised'.
    So I guess the answer is "No .net 4 discovery does not solve this problem"?
    Wednesday, December 09, 2009 12:32 AM
  • The Dynamic Proxy downloads the metadata from the service and creates the binding at runtime. So yes, it can infer all the binding properties specified in the WSDL.
    Wednesday, December 09, 2009 12:47 AM
  • To expand a little more on what Amadeo stated, what you'll need to do is gather the MEX endpoint of the service. From the metadata you can create a client proxy binding. Locating the mex endpoint can be a little tricky. You can add it as part of the metadata for your service endpoint. Alternatively you can make your MEX endpoint discoveryable and decorate it with a scope that has your contract in it.

    Once you have a MEX endpoint, you should be able to build the appropriate client binding.

    There is another solution to this also. You can insert a Router in the middle of your solution. The router can bridge messages between different binding. There some caveats to this solution as well. Such as you'll need the router to respond on the behalf of your service, or you'll need the service to provide the endpoint address of the router, or (the easiest solution) is to add a proxy and have the proxy respond back with the endpoint of the router.

    It would be great to understand your scenario a little better. Such as when do you need to generate the client proxy, is it on the fly, or is it once. Are you creating it part of the client open call or as part of pre-setup phase.

    We'll provide some code shwoing the latter example on the WCF discovery blog shortly. http://blogs.msdn.com/discovery/

    Thanks,
    Anurag

    Thursday, December 10, 2009 10:09 PM
  • Thanks for the great replies guys,

    I wasnt aware that the MEX actually contained binding configuration information - hearing that it does greatly improve the situation.

    The scenario that I am working on does involve a router, the point being that I have a server on the internet which has numerous WCF endpoints, my router sits within the intranet, and provides UDP discovery capabilities to all intranet clients for all the services on the internet. The server and clients should be able to be versioned independently of the router.

    So, the router is aware of the discovery endpoint URI on the internet, and uses it to discover all remote services. These service endpoints are then added dynamically at runtime to the UDP discovery endpoint within the intranet, thereby re-advertising the services to local clients over UDP, making them truly zero-config (and perhaps doing so with a different binding, such as binary now that we are inside the firewall).

    This means that the router needs to be able to discover the binding configuration of the internet-based endpoint, so that it may relay messages.
    I have this working, but I am appending custom strings to the advertisement to describe the required binding settings. I think your dynamic proxy solution will be a good drop-in replacement, I shall give it a try a next opportunity.
    Thursday, December 10, 2009 11:00 PM
  • I still  wonder why the binding is not part of the discovery information. You need to communicate remotly once to discover and then again just to get binding. I noticed you can add extra information in the registration of a new service, can we not put binding info there based on the ServiceDescription, and then pass it back via the Extension array?
    Tuesday, December 15, 2009 1:21 PM
  • Discovery allows for a lot of customization, so yes what you're suggesting Mike is totally possible. If you know your binding ahead of time you can serialize it and send it along with your service metadata extension elements. However, we don't do it by default.

    Integrating the binding information is something we'll consider for v. next. So if you feel that this is a must have feature do let us know. We're listening =)
    Wednesday, December 16, 2009 5:16 AM
  • Hi,

    Thanks for the confirmation regarding the binding, I will try it and I will re-post when I am done. I believe the binding should be there, after all WCF is all about the ABC and not just the A and C

    Happy Holidays everyone
    Friday, December 18, 2009 12:51 AM
  • If you look at the WS-Discovery specification you see that the binding is not emphasized. Additionally, WCF is interoperable, at least where it conforms to the WS-* standards; bindings like net.Tcp are proprietary.

     

    You could always use the metadata extensions to define a custom class that could represent an endpoint in a .Net context. You could then rehydrate the xml on the client side to produce your bindings, etc.

    http://docs.oasis-open.org/ws-dd/discovery/1.1/os/wsdd-discovery-1.1-spec-os.pdf

    Friday, January 15, 2010 6:58 PM
  • Here is an example which shows how to import WSDL metadata which hold A, C and B :)

     

     

    DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());
    FindCriteria criteria = FindCriteria.CreateMetadataExchangeEndpointCriteria();
    criteria.MaxResults = 1;
     

    FindResponse discovered = discoveryClient.Find(criteria);

    discoveryClient.Close();

    CustomBinding binding = new CustomBinding(new HttpTransportBindingElement());

    MetadataExchangeClient mexClient = new MetadataExchangeClient(binding);

    MetadataSet metadata = mexClient.GetMetadata(discovered.Endpoints[0].Address);

    MetadataImporter importer = new WsdlImporter(metadata);

    ServiceEndpointCollection endpoints = importer.ImportAllEndpoints();

    ISampleService proxy =
    ChannelFactory<ISampleService>.CreateChannel(endpoints[0].Binding, endpoints[0].Address);

    proxy.DoWork();


    Note that service has to provide endpoinf od kind=mexendpoint additionally to Discovery Endpoint

    <

     

     

     

    endpoint kind="udpDiscoveryEndpoint"/>

    <

     

     

     

    endpoint kind = "mexEndpoint" address = "MEX" binding = "mexHttpBinding" />


    Hope this helps.

    Tuesday, February 23, 2010 10:19 PM
  • I haved tried it and it worked... I got binding information with the metadata. I wrote about this here 

    http://mikeperetz.blogspot.com/2010/04/wcf-40-service-discovery-adding-binding.html

    Sunday, April 11, 2010 5:25 AM