5

Stworzyłem WCF klienta/serwera. To, czego chcę, to kiedy wysyłam wiadomość do serwera z tego klienta i zerwanie połączenia z jakiegokolwiek powodu, klient zamyka na przykład, w jaki sposób ten klient może uzyskać odpowiedź, gdy jest znowu dostępny?Jak otrzymać odpowiedź z serwera w niezawodnym komunikacie WCF po zerwaniu połączenia

Czy można ustawić sesję lub coś pomiędzy klientem a serwerem?

Mój kod klienta jest:

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); 
} 

Mój kod serwera jest:

[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; 
    } 
} 

i serwer konfiguracje W skrócie:

<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> 
+0

Nie można po prostu powtórzyć połączenia w przypadku niepowodzenia? – Evk

+0

Nie chcę ponownie robić tego samego na serwerze. –

+0

Usługa WCF jest domyślnie bezstanowa, a taka jest natura usługi, ale można użyć stanu. W każdym razie, w twoim scenariuszu, myślę, że możesz rozwiązać buforowanie wyniku dla następnego połączenia, unikając ponownego przetwarzania. –

Odpowiedz

2

Jeden rozsądne podejście tutaj jest użycie asynchronicznego żądania -odpowiedź. Oznacza to, że klient nie czeka, aż serwer wykona swoją pracę, po prostu odpala żądanie i zapomina. Po zakończeniu serwera oddzwania do klienta z wynikami operacji. W szczególności WCF ma umowy dwustronne, aby to osiągnąć: http://www.codeproject.com/Articles/491844/A-Beginners-Guide-to-Duplex-WCF.

Gdy odpowiedź serwera jest gotowa, próbuje dostarczyć ją do klienta. Jeśli to się nie powiedzie, serwer może spróbować ponownie później, aż do osiągnięcia sukcesu lub przekroczenia limitu czasu.

Jeśli zastosujesz się do tego wzorca, klient powinien mieć jakiś unikalny identyfikator, tak aby nawet po przywróceniu połączenia - serwer wie, że jest to ten sam klient i wie, na które odpowiedzi oczekuje ten klient.

Innym podejściem byłoby buforowanie wyników na serwerze przez pewien (ograniczony) czas. Możesz podać unikalny identyfikator dla każdego żądania, a następnie na serwerze sprawdzić, czy żądanie o takim identyfikatorze zostało już zakończone, a jeśli tak, natychmiast dostarczyć wyniki. W przeciwnym razie odpowiedź na proces i buforuj go przez ograniczony czas, na wypadek gdyby klient spróbował nieco później. Na kliencie - po prostu spróbuj ponownie po awarii.