Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to receive a response from server in WCF reliable messaging after connection cuts

So I created Client/Server WCF. What I want is when I send message to the server from this client and the connection cuts for any reason , client shuts down for example, how could this client get the response when it is availabe again ?

Is it possible to set a session or something like between the client and the server?

My client code is :

private static void Main(string[] args)
{
    var client = new FlipCaseServiceClient("ReliableMessageService");
    var sd = new StringData { FirstName = "Turgut", LastName = "Kançeltik" };

    var fullName = client.GetFullName(ref sd);

    Console.WriteLine(fullName);
}

My Server code is :

[DeliveryRequirements(RequireOrderedDelivery = true)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)]
public class FlipCaseService : IFlipCaseService
{
    public string GetFullName(ref StringData stringData)
    {
        var fullName = $"{stringData.FirstName} {stringData.LastName}";

        stringData.FullName = fullName;
        return fullName;
    }
}

And server configurations in summary :

<service behaviorConfiguration="ServiceBehaviorMetaData" name="FlipCaseService.FlipCaseService" >
  <endpoint name="ReliableMessageService" address="flipcase/wsAddress" binding="wsHttpBinding" bindingConfiguration="BindingReliableMessaging" contract="FlipCaseService.IFlipCaseService" >
     <identity>
        <dns value="localhost" />
     </identity>
  </endpoint>
</service>

<bindings>
  <wsHttpBinding>
    <binding name="BindingReliableMessaging">
      <reliableSession enabled="true" inactivityTimeout="00:10:00"/>
    </binding>
  </wsHttpBinding>      
</bindings>

<behavior name="ServiceBehaviorMetaData">
  <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8080/flipcase/metadata" />
  <serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
like image 687
Turgut Kanceltik Avatar asked Oct 30 '22 17:10

Turgut Kanceltik


1 Answers

One reasonable approach here is to use asynchronous request-response. That means client does not wait for server to complete it's work, just fires request and forgets. When server is done, he calls client back with the results of operation. Specifically WCF has duplex contracts to achieve that: http://www.codeproject.com/Articles/491844/A-Beginners-Guide-to-Duplex-WCF.

When server response is ready, it tries to deliver it to the client. If that fails, server can retry again later, until success or some timeout is reached.

If you follow this pattern, client should have some unique identifier, so that even if connection is restored - server knows it is the same client and it knows which responses are awaited by this client.

Another approach would be to cache results on server for some (limited) time. You can provide unique id for each request, then on server check if request with such id was completed already and if yes - deliver the results immediatly. Otherwise, process response and cache it for limited time, in case client will retry a bit later. On client - just retry on failure.

like image 192
Evk Avatar answered Nov 15 '22 06:11

Evk