Udostępnij za pośrednictwem


Uzyskiwanie dostępu do usług za pomocą klienta

Aplikacje klienckie muszą tworzyć, konfigurować i używać obiektów klienta lub kanału WCF do komunikowania się z usługami. Temat Omówienie klienta programu WCF zawiera omówienie obiektów i kroków związanych z tworzeniem podstawowych obiektów klienta i kanału oraz ich używaniem.

Ten temat zawiera szczegółowe informacje na temat niektórych problemów z aplikacjami klienckimi oraz obiektami klienta i kanału, które mogą być przydatne w zależności od scenariusza.

Omówienie

W tym temacie opisano zachowanie i problemy związane z:

  • Okresy istnienia kanału i sesji.

  • Obsługa wyjątków.

  • Zrozumienie problemów z blokowaniem.

  • Interakcyjne inicjowanie kanałów.

Okresy istnienia kanału i sesji

Aplikacje programu Windows Communication Foundation (WCF) obejmują dwie kategorie kanałów, datagram i sesji.

Kanał datagramu to kanał, w którym wszystkie komunikaty są niekorzystywane. W przypadku kanału datagramu, jeśli operacja wejściowa lub wyjściowa zakończy się niepowodzeniem, następna operacja jest zwykle nie dotyczyć, a ten sam kanał może zostać ponownie użyty. W związku z tym kanały datagramu zwykle nie powodują błędów.

Kanały sesji są jednak kanałami z połączeniem z innym punktem końcowym. Komunikaty w sesji po jednej stronie są zawsze skorelowane z tą samą sesją po drugiej stronie. Ponadto obaj uczestnicy sesji muszą zgodzić się, że wymagania ich rozmowy zostały spełnione, aby ta sesja została uznana za pomyślną. Jeśli nie mogą się zgodzić, kanał sesji może zostać uszkodzony.

Otwórz klientów jawnie lub niejawnie, wywołując pierwszą operację.

Uwaga

Próba jawnego wykrycia uszkodzonych kanałów sesji nie jest zwykle przydatna, ponieważ w przypadku powiadomienia zależy od implementacji sesji. Na przykład ze względu na System.ServiceModel.NetTcpBinding to, że (z wyłączoną niezawodną sesją) wyświetla sesję połączenia TCP, jeśli nasłuchujesz ICommunicationObject.Faulted zdarzenia w usłudze lub klienta, który prawdopodobnie zostanie szybko powiadomiony w przypadku awarii sieci. Jednak niezawodne sesje (ustanowione przez powiązania, w których System.ServiceModel.Channels.ReliableSessionBindingElement włączono) są przeznaczone do izolowania usług od małych awarii sieci. Jeśli sesję można ponownie opublikować w rozsądnym okresie, to to samo powiązanie — skonfigurowane pod kątem niezawodnych sesji — może nie spowodować błędu, dopóki przerwa nie będzie kontynuowana przez dłuższy czas.

Większość powiązań dostarczanych przez system (które uwidacznia kanały w warstwie aplikacji) domyślnie używają sesji, ale System.ServiceModel.BasicHttpBinding nie. Aby uzyskać więcej informacji, zobacz Using Sessions (Korzystanie z sesji).

Właściwe użycie sesji

Sesje umożliwiają określenie, czy cała wymiana komunikatów została ukończona i czy obie strony uznały ją za pomyślną. Zaleca się otwarcie kanału przez aplikację wywołującą, użycie jej i zamknięcie kanału w jednym bloku try. Jeśli kanał sesji jest otwarty, a ICommunicationObject.Close metoda jest wywoływana raz, a wywołanie zostanie zwrócone pomyślnie, sesja zakończyła się pomyślnie. W takim przypadku powodzenie oznacza, że wszystkie dostawy gwarantują, że określone powiązanie zostało spełnione, a druga strona nie wywołała kanału przed wywołaniem ICommunicationObject.Abort metody Close.

W poniższej sekcji przedstawiono przykład tego podejścia klienta.

Obsługa wyjątków

Obsługa wyjątków w aplikacjach klienckich jest prosta. Jeśli kanał jest otwarty, używany i zamknięty wewnątrz bloku try, konwersacja zakończyła się pomyślnie, chyba że zostanie zgłoszony wyjątek. Zazwyczaj, jeśli zostanie zgłoszony wyjątek, konwersacja zostanie przerwana.

Uwaga

Korzystanie z instrukcji using (Using w Visual Basic) nie jest zalecane. Wynika to z faktu, że koniec instrukcji using może powodować wyjątki, które mogą maskować inne wyjątki, o których może być konieczne. Aby uzyskać więcej informacji, zobacz Use Close and Abort to release WCF client resources (Używanie zamknij i abort do wydawania zasobów klienta programu WCF).

Poniższy przykład kodu przedstawia zalecany wzorzec klienta przy użyciu bloku try/catch, a nie instrukcji using .

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Microsoft.WCF.Documentation;

public class Client
{
  public static void Main()
  {
    // Picks up configuration from the config file.
    SampleServiceClient wcfClient = new SampleServiceClient();
    try
    {
      // Making calls.
      Console.WriteLine("Enter the greeting to send: ");
      string greeting = Console.ReadLine();
      Console.WriteLine("The service responded: " + wcfClient.SampleMethod(greeting));

      Console.WriteLine("Press ENTER to exit:");
      Console.ReadLine();

      // Done with service.
      wcfClient.Close();
      Console.WriteLine("Done!");
    }
    catch (TimeoutException timeProblem)
    {
      Console.WriteLine("The service operation timed out. " + timeProblem.Message);
      Console.ReadLine();
      wcfClient.Abort();
    }
    catch (FaultException<GreetingFault> greetingFault)
    {
      Console.WriteLine(greetingFault.Detail.Message);
      Console.ReadLine();
      wcfClient.Abort();
    }
    catch (FaultException unknownFault)
    {
      Console.WriteLine("An unknown exception was received. " + unknownFault.Message);
      Console.ReadLine();
      wcfClient.Abort();
    }
    catch (CommunicationException commProblem)
    {
      Console.WriteLine("There was a communication problem. " + commProblem.Message + commProblem.StackTrace);
      Console.ReadLine();
      wcfClient.Abort();
    }
  }
}

Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports Microsoft.WCF.Documentation

Public Class Client
    Public Shared Sub Main()
        ' Picks up configuration from the config file.
        Dim wcfClient As New SampleServiceClient()
        Try
            ' Making calls.
            Console.WriteLine("Enter the greeting to send: ")
            Dim greeting As String = Console.ReadLine()
            Console.WriteLine("The service responded: " & wcfClient.SampleMethod(greeting))

            Console.WriteLine("Press ENTER to exit:")
            Console.ReadLine()

            ' Done with service. 
            wcfClient.Close()
            Console.WriteLine("Done!")
        Catch timeProblem As TimeoutException
            Console.WriteLine("The service operation timed out. " & timeProblem.Message)
            Console.ReadLine()
            wcfClient.Abort()
        Catch greetingFault As FaultException(Of GreetingFault)
            Console.WriteLine(greetingFault.Detail.Message)
            Console.ReadLine()
            wcfClient.Abort()
        Catch unknownFault As FaultException
            Console.WriteLine("An unknown exception was received. " & unknownFault.Message)
            Console.ReadLine()
            wcfClient.Abort()
        Catch commProblem As CommunicationException
            Console.WriteLine("There was a communication problem. " & commProblem.Message + commProblem.StackTrace)
            Console.ReadLine()
            wcfClient.Abort()
        End Try
    End Sub
End Class

Uwaga

Sprawdzanie wartości ICommunicationObject.State właściwości jest warunkiem wyścigu i nie jest zalecane, aby określić, czy ponownie użyć lub zamknąć kanał.

Kanały datagramu nigdy nie są błędne, nawet jeśli wyjątki wystąpią po ich zamknięciu. Ponadto klienci niedupleksowi, którzy nie mogą uwierzytelniać się przy użyciu bezpiecznej konwersacji, zwykle zgłaszają błąd System.ServiceModel.Security.MessageSecurityException. Jeśli jednak klient dupleksu używający bezpiecznej konwersacji nie może się uwierzytelnić, klient otrzyma zamiast tego System.TimeoutException .

Aby uzyskać więcej informacji na temat pracy z informacjami o błędach na poziomie aplikacji, zobacz Określanie i obsługa błędów w kontraktach i usługach. Oczekiwane wyjątki opisują oczekiwane wyjątki i pokazują, jak je obsługiwać. Aby uzyskać więcej informacji na temat obsługi błędów podczas opracowywania kanałów, zobacz Obsługa wyjątków i błędów.

Blokowanie i wydajność klienta

Gdy aplikacja synchronicznie wywołuje operację request-reply, klient blokuje wartość zwracaną do momentu odebrania wartości zwracanej lub zgłoszenia wyjątku (takiego jak System.TimeoutException). To zachowanie jest podobne do zachowania lokalnego. Gdy aplikacja synchronicznie wywołuje operację na obiekcie lub kanale klienta WCF, klient nie zwraca, dopóki warstwa kanału nie będzie mogła zapisać danych w sieci lub do momentu zgłoszenia wyjątku. I chociaż wzorzec wymiany komunikatów jednokierunkowych (określony przez oznaczenie operacji z ustawioną OperationContractAttribute.IsOneWay wartością true) może sprawić, że niektórzy klienci będą mogli szybciej reagować, jednokierunkowe operacje mogą również blokować, w zależności od powiązania i komunikatów, które zostały już wysłane. Operacje jednokierunkowe dotyczą tylko wymiany komunikatów, nie więcej i nie mniej. Aby uzyskać więcej informacji, zobacz Usługi jednokierunkowe.

Duże fragmenty danych mogą spowalniać przetwarzanie klienta niezależnie od wzorca wymiany komunikatów. Aby dowiedzieć się, jak rozwiązywać te problemy, zobacz Duże dane i przesyłanie strumieniowe.

Jeśli aplikacja musi wykonać więcej pracy podczas wykonywania operacji, należy utworzyć parę metod asynchronicznych w interfejsie kontraktu usługi, który implementuje klient WCF. Najprostszym sposobem jest użycie przełącznika /async narzędzia ServiceModel Metadata Tool (Svcutil.exe). Przykład można znaleźć w temacie How to: Call Service Operations Asynchronously (Instrukcje: asynchronicznie wywoływanie operacji usługi).

Aby uzyskać więcej informacji na temat zwiększania wydajności klienta, zobacz Aplikacje klienckie warstwy środkowej.

Umożliwianie użytkownikowi dynamicznego wybierania poświadczeń

Interfejs IInteractiveChannelInitializer umożliwia aplikacjom wyświetlanie interfejsu użytkownika, który umożliwia użytkownikowi wybranie poświadczeń, za pomocą których kanał jest tworzony przed rozpoczęciem limitu czasu.

Deweloperzy aplikacji mogą korzystać z wstawionego IInteractiveChannelInitializer obiektu na dwa sposoby. Aplikacja kliencka może wywołać ClientBase<TChannel>.DisplayInitializationUI wersję asynchroniczną lub IClientChannel.DisplayInitializationUI (lub asynchroniczną) przed otwarciem kanału (podejście jawne) lub wywołać pierwszą operację (niejawne podejście).

W przypadku korzystania z niejawnego podejścia aplikacja musi wywołać pierwszą operację ClientBase<TChannel> w rozszerzeniu lub IClientChannel . Jeśli wywołuje coś innego niż pierwsza operacja, zgłaszany jest wyjątek.

W przypadku korzystania z jawnego podejścia aplikacja musi wykonać następujące kroki w następującej kolejności:

  1. ClientBase<TChannel>.DisplayInitializationUI Wywołaj wersję asynchroniczną lub IClientChannel.DisplayInitializationUI lub (lub asynchroniczną).

  2. Po zwróceniu inicjatorów wywołaj metodę Open w IClientChannel obiekcie lub na IClientChannel obiekcie zwróconym ClientBase<TChannel>.InnerChannel z właściwości .

  3. Operacje wywoływania.

Zaleca się, aby aplikacje jakości produkcyjnej kontrolować proces interfejsu użytkownika, stosując jawne podejście.

Aplikacje korzystające z niejawnego podejścia wywołują inicjatory interfejsu użytkownika, ale jeśli użytkownik aplikacji nie odpowie w okresie przekroczenia limitu czasu wysyłania powiązania, zgłaszany jest wyjątek, gdy interfejs użytkownika zwraca.

Zobacz też