Udostępnij za pośrednictwem


Usługi jednokierunkowe

Domyślnym zachowaniem operacji usługi jest wzorzec żądania-odpowiedź. We wzorcu żądania-odpowiedź klient czeka na komunikat odpowiedzi, nawet jeśli operacja usługi jest reprezentowana w kodzie jako void metoda. W przypadku operacji jednokierunkowej jest przesyłany tylko jeden komunikat. Odbiorca nie wysyła wiadomości odpowiedzi ani nie oczekuje jej od nadawcy.

Użyj wzorca projektowego jednokierunkowego:

Gdy operacja jest jednokierunkowa, nie ma komunikatu odpowiedzi w celu przeniesienia informacji o błędzie z powrotem do klienta. Warunki błędów można wykrywać przy użyciu funkcji powiązania bazowego, takich jak niezawodne sesje, lub projektując kontrakt usługi dwustronnej, który korzysta z dwóch operacji jednokierunkowych — jednokierunkowego kontraktu od klienta do usługi w celu wywołania operacji usługi i innego kontraktu jednokierunkowego między usługą a klientem, aby usługa mogła wysyłać błędy zwrotne do klienta przy użyciu wywołania zwrotnego implementowane przez klienta.

Aby utworzyć jednokierunkowy kontrakt usługi, zdefiniuj kontrakt usługi, zastosuj OperationContractAttribute klasę do każdej operacji i ustaw IsOneWay właściwość na true, jak pokazano w poniższym przykładowym kodzie.

[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]  
public interface IOneWayCalculator  
{  
    [OperationContract(IsOneWay=true)]  
    void Add(double n1, double n2);  
    [OperationContract(IsOneWay = true)]  
    void Subtract(double n1, double n2);  
    [OperationContract(IsOneWay = true)]  
    void Multiply(double n1, double n2);  
    [OperationContract(IsOneWay = true)]  
    void Divide(double n1, double n2);  
}  

Pełny przykład można znaleźć w przykładzie One-Way .

Klienci blokujący operacje jednokierunkowe

Należy pamiętać, że chociaż niektóre aplikacje jednokierunkowe zwracają dane wychodzące natychmiast po zapisaniu danych wychodzących do połączenia sieciowego, w kilku scenariuszach implementacja powiązania lub usługi może spowodować zablokowanie korzystania z operacji jednokierunkowych przez klienta WCF. W aplikacjach klienckich WCF obiekt klienta WCF nie zwraca się, dopóki dane wychodzące nie zostały zapisane w połączeniu sieciowym. Dotyczy to wszystkich wzorców wymiany komunikatów, w tym operacji jednokierunkowych; Oznacza to, że każdy problem podczas zapisywania danych w transporcie uniemożliwia klientowi powrót. W zależności od problemu wynik może być wyjątkiem lub opóźnieniem wysyłania komunikatów do usługi.

Jeśli na przykład transport nie może odnaleźć punktu końcowego, wyjątek System.ServiceModel.EndpointNotFoundException jest zgłaszany bez znacznego opóźnienia. Jednak z jakiegoś powodu usługa nie może odczytać danych z przewodu, co uniemożliwia powrót operacji wysyłania transportu klienta. W takich przypadkach, jeśli Binding.SendTimeout okres powiązania transportu klienta zostanie przekroczony, jest zgłaszany — System.TimeoutException ale nie do momentu przekroczenia limitu czasu. Istnieje również możliwość wyzwolenia tak wielu komunikatów w usłudze, że usługa nie może przetworzyć ich w określonym punkcie. W takim przypadku również jednokierunkowy klient blokuje, dopóki usługa nie będzie mogła przetworzyć komunikatów lub do momentu zgłoszenia wyjątku.

Inną odmianą jest sytuacja, w której właściwość usługi ServiceBehaviorAttribute.ConcurrencyMode jest ustawiona na Single , a powiązanie używa sesji. W takim przypadku dyspozytor wymusza porządkowanie przychodzących komunikatów (wymaganie sesji), co uniemożliwia odczytywanie kolejnych komunikatów z sieci do momentu przetworzenia poprzedniego komunikatu dla tej sesji. Ponownie klient blokuje, ale to, czy występuje wyjątek, zależy od tego, czy usługa może przetwarzać dane oczekujące przed ustawieniami limitu czasu na kliencie.

Niektóre z tych problemów można rozwiązać, wstawiając bufor między obiektem klienta a operacją wysyłania transportu klienta. Na przykład użycie wywołań asynchronicznych lub użycie kolejki komunikatów w pamięci może umożliwić szybkie zwracanie obiektu klienta. Obie metody mogą zwiększyć funkcjonalność, ale rozmiar puli wątków i kolejki komunikatów nadal wymuszają limity.

Zamiast tego zaleca się sprawdzenie różnych kontrolek w usłudze oraz na kliencie, a następnie przetestowanie scenariuszy aplikacji w celu określenia najlepszej konfiguracji po obu stronach. Jeśli na przykład użycie sesji blokuje przetwarzanie komunikatów w usłudze, możesz ustawić ServiceBehaviorAttribute.InstanceContextMode właściwość na PerCall wartość , aby każdy komunikat mógł być przetwarzany przez inne wystąpienie usługi i ustawić ConcurrencyMode wartość na Multiple , aby umożliwić więcej niż jeden wątek wysyłania komunikatów jednocześnie. Innym podejściem jest zwiększenie limitów przydziału odczytu usługi i powiązań klienta.

Zobacz też