Azure service fabric - service communication - reverse-proxy

As I know, in Azure service fabric, service communication can be possibles either by directly accessing the endpoints (or) reverse-proxy.
Currently I'm directly accessing the other service endpoints using below code:
var service = $"fabric://myapp/**service1**";
var servicePartitionResolver = ServicePartitionResolver.GetDefault();
var partition = await servicePartitionResolver.ResolveAsync(new System.Uri(service),
new ServicePartitionKey(), default(CancellationToken));
var serviceEndpointJson = partition.GetEndpoint().Address;
string endpointUrl = JObject.Parse(serviceEndpointJson)["Endpoints"][string.Empty].Value<string>();
Will this approach work if service1 instance is not available on expected node1 but available on node2 of the SF cluster?
Is directly accessing service endpoints - approach uses 'Naming Service' like reverse-proxy approach to identify the requested service address via service url?
Any disadvantages of using above direct access call implementation to discover services for internal service communication?

The resolved endpoint should work, but you can do this in a simpler way:
Use the built-in DNS to communicate between services using HTTP.
Use SF Remoting to communicate between services.
The DNS allows you to get an endpoint by passing in the application and target service details.
SF remoting works in a similar way. The main advantage of the last, is that the SF remoting client has built-in transient error handling (it retries calls whenever the remote service is temporarily unavailable).

Related

Javascript Client for Windows Azure Service Bus Relay service?

Is it possible to consume a WCF service via a Windows Azure Service Bus Relay in a JavaScript client?
You can setup a WebHttpRelay service that can be accessed via GET calls in JavaScript if you are using Node.
EDIT: This gives a good overview on how to setup a WCF service to support CORS. You need to enable it on your service to allow calls from a different host.

"Re-announcing" service periodically when using WCF ServiceDiscoveryBehavior announcement endpoint?

I have a Managed Discovery Service hosted with a known URI. I have a discoverable service that when it starts, it announces itself using an AnnouncementEndpoint added to the ServiceDiscoveryBehavior of the service.
The specific use case I would like to solve is the following:
Managed Discovery service starts.
A discoverable service starts and announces itself to the Managed Discovery service.
The Managed Discovery service is restarted (for any various possible reasons).
How then does the discoverable service refresh itself (re-announce) to the Managed Discovery service?
I know the Managed Discovery service can persist endpoints and restore them upon start but I want everything to be dynamic and self repairing so that there's no chance of stale endpoint information.
An alternative use case would be:
An existing discoverable service is running.
A new Managed Discovery service is brought online.
How do we force or invoke the same Announcement service contract call to the new Managed Discovery service?
I hope this is enough information about what I want to accomplish.
I found the answer myself. In the scenario where you need to control announcements outside of the ServiceDiscoveryBehavior , you would use the AnnouncementClient class.
AnnouncementClient client = new AnnouncementClient(announcementEndpoint);
var endpointDiscoveryMetadata = EndpointDiscoveryMetadata.FromServiceEndpoint(netTcpEndpoint);
client.AnnounceOnline(endpointDiscoveryMetadata);

Auto-resolving a hostname in WCF Metadata Publishing

I am running a self-hosted WCF service. In the service configuration, I am using localhost in my BaseAddresses that I hook my endpoints to. When trying to connect to an endpoint using the WCF test client, I have no problem connecting to the endpoint and getting the metadata using the machine's name. The problem that I run into is that the client that is generated from metadata uses localhost in the endpoint URLs it wants to connect to. I'm assuming that this is because localhost is the endpoint URL published by metadata. As a result, any calls to the methods on the service will fail since localhost on the calling machine isn't running the service.
What I would like to figure out is if it is possible for the service metadata to publish the proper URL to a client depending on the client who is calling it. For example, if I was requesting the service metadata from a machine on the same network as the server the endpoint should be net.tcp://MYSERVER:1234/MyEndpoint. If I was requesting it from a machine outside the network, the URL should be net.tcp://MYSERVER.mydomain.com:1234/MyEndpoint. And obviously if the client was on the same machine, THEN the URL could be net.tcp://localhost:1234/MyEndpoint.
Is this just a flaw in the default IMetadataExchange contract? Is there some reason the metadata needs to publish the information in a non-contextual way? Is there another way I should be configuring my BaseAddresses in order to get the functionality I want?
Thanks,
Mike
What .NET version are you using? If you're using .NET 4.0, add the UseRequestHeadersForMetadataAddressBehavior to your service host:
UseRequestHeadersForMetadataAddressBehavior urh =
new UseRequestHeadersForMetadataAddressBehavior();
serviceHost.Description.Behaviors.Add(urh);
Obviously, this needs to be done prior to opening the service host.
If you're using .NET 3.5, there's a hotfix that adds this behavior: support.microsoft.com/kb/971842.

All about wcf client

When I deploy the same service on different machines as they have different information that I need , how can I use my client gracely to consume these service .
You need to define the service endpoint you want to connect to in your client's config.
You cannot define a list of endpoints - if you need load-balancing features, you need to implement those on the server side and "hide" them behind a single service endpoint.
With .NET 4 and WCF 4, you have new capabilities you could check out:
WCF 4 has a new routing service which you can use to get called on a single URL, and you have control over how to "distribute" those calls to the actual back-end servers
WCF 4 also supports dynamic service discovery, so you could potentially just "yell out onto the network" and get back one service endpoint address that supports your contract you're interested in
Resources:
Developer's Introduction to WCF 4
10-4 Show on WCF 4 Routing Service
Content-based routing with WCF 4
WCF 4.0 Routing Service
WCF 4.0 Routing Service - Failover
Using WS-Discovery in WCF 4.0
Ad-hoc Discovery with Probing messages
It sounds like you want to connect to BOTH servers. you say they have different data that you need. Well, if you already know how to make a client to one of them, the easiest way is to define an entire other client to access the second one. You can define as many clients as you want in the config file. Then just call them both in code.

WCF Callback Service hosted over basicHttpBinding and wsDualHttpBinding

I have a callback service that is hosted over wsDualHttpBinding. I'm looking to add a client that will poll for the data rather than receive the callback (will be a mobile device using wince for demo purposes). I was curious what the best way to do this is? You cannot create a client proxy using NetCFSvcUtil with a service hosted with wsDualHttpBinding (I understand that), but you cannot host a callback service over basicHttpBinding. I really need the same service hosted over both basicaHttpBinding (clients will poll for data) and wsDualHttpBinding (callback will notify clients of data). Any ideas on the best way to handle this without creating two separate services to host the same data?
What do you mean by two separate services hosting the same data? Do you expect to share same service instance to handle both wsDualHttpBinding and basicHttpBinding requests?
Your current problem is that service interface for duplex communication cannot be used for basicHttpBinding. You have to create second service contract and implement it in the same service. In that case you can expose two endpoints for the service: one duplex with WSDualHttpBinding and one with BasicHttpBinding. Endpoints must have different relative addresses. From the perspective of the client those endpoints are separate services - each of them requires separate client proxy. So unless your service is singleton you will have new service instance for each client proxy. New service instance means no data sharing.
Thera are some possibilities to modify this behavior but it means replacing Instance provider.