Dela via


Gör så här: Skapa ett Duplex-kontrakt

Det här avsnittet visar de grundläggande stegen för att skapa metoder som använder ett dubbelriktade (dubbelriktade) kontrakt. Med ett dubbelsidigt kontrakt kan klienter och servrar kommunicera med varandra oberoende av varandra så att de kan initiera anrop till varandra. Duplex-kontraktet är ett av tre meddelandemönster som är tillgängliga för WCF-tjänster (Windows Communication Foundation). De andra två meddelandemönstren är enkelriktade och begärandesvar. Ett dubbelsidigt kontrakt består av två enkelriktade kontrakt mellan klienten och servern och kräver inte att metodanropen korreleras. Använd den här typen av kontrakt när tjänsten måste fråga klienten om mer information eller uttryckligen generera händelser på klienten. Mer information om hur du skapar ett klientprogram för ett duplex-kontrakt finns i How to: Access Services with a Duplex Contract (Så här gör du: Åtkomsttjänster med ett Duplex-kontrakt). Ett arbetsexempel finns i Duplex-exemplet .

Så här skapar du ett duplex-kontrakt

  1. Skapa det gränssnitt som utgör serversidan av duplex-kontraktet.

  2. Tillämpa klassen på ServiceContractAttribute gränssnittet.

    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples", SessionMode=SessionMode.Required,
                     CallbackContract=typeof(ICalculatorDuplexCallback))]
    public interface ICalculatorDuplex
    {
        [OperationContract(IsOneWay=true)]
        void Clear();
        [OperationContract(IsOneWay = true)]
        void AddTo(double n);
        [OperationContract(IsOneWay = true)]
        void SubtractFrom(double n);
        [OperationContract(IsOneWay = true)]
        void MultiplyBy(double n);
        [OperationContract(IsOneWay = true)]
        void DivideBy(double n);
    }
    
    <ServiceContract(Namespace:="http://Microsoft.ServiceModel.Samples", SessionMode:=SessionMode.Required, _
                    CallbackContract:=GetType(ICalculatorDuplexCallback))> _
    Public Interface ICalculatorDuplex
    
        <OperationContract(IsOneWay:=True)> _
        Sub Clear()
        <OperationContract(IsOneWay:=True)> _
        Sub AddTo(ByVal n As Double)
        <OperationContract(IsOneWay:=True)> _
        Sub SubtractFrom(ByVal n As Double)
        <OperationContract(IsOneWay:=True)> _
        Sub MultiplyBy(ByVal n As Double)
        <OperationContract(IsOneWay:=True)> _
        Sub DivideBy(ByVal n As Double)
    End Interface
    
    
  3. Deklarera metodsignaturerna i gränssnittet.

  4. Tillämpa klassen på OperationContractAttribute varje metodsignatur som måste ingå i det offentliga kontraktet.

  5. Skapa motringningsgränssnittet som definierar den uppsättning åtgärder som tjänsten kan anropa på klienten.

    public interface ICalculatorDuplexCallback
    {
        [OperationContract(IsOneWay = true)]
        void Equals(double result);
        [OperationContract(IsOneWay = true)]
        void Equation(string eqn);
    }
    
    Public Interface ICalculatorDuplexCallback
        <OperationContract(IsOneWay:=True)> _
        Sub Equals(ByVal result As Double)
        <OperationContract(IsOneWay:=True)> _
        Sub Equation(ByVal eqn As String)
    end interface
    
    
  6. Deklarera metodsignaturerna i motringningsgränssnittet.

  7. Tillämpa klassen på OperationContractAttribute varje metodsignatur som måste ingå i det offentliga kontraktet.

  8. Länka de två gränssnitten till ett duplex-kontrakt genom att ange CallbackContract egenskapen i det primära gränssnittet till typen av motringningsgränssnitt.

Anropa metoder på klienten

  1. I tjänstens implementering av det primära kontraktet deklarerar du en variabel för återanropsgränssnittet.

  2. Ange variabeln till den objektreferens som returneras av GetCallbackChannel -metoden för OperationContext klassen.

    ICalculatorDuplexCallback callback = null;
    
    Dim callback As ICalculatorDuplexCallback
    
    callback = OperationContext.Current.GetCallbackChannel<ICalculatorDuplexCallback>();
    
    callback = OperationContext.Current.GetCallbackChannel(Of ICalculatorDuplexCallback)()
    
  3. Anropa metoderna som definierats av motringningsgränssnittet.

Exempel

I följande kodexempel visas duplexkommunikation. Tjänstens kontrakt innehåller tjänståtgärder för att gå framåt och bakåt. Klientens kontrakt innehåller en tjänståtgärd för att rapportera sin position.

// Define a duplex service contract.
// A duplex contract consists of two interfaces.
// The primary interface is used to send messages from client to service.
// The callback interface is used to send messages from service back to client.
// ICalculatorDuplex allows one to perform multiple operations on a running result.
// The result is sent back after each operation on the ICalculatorCallback interface.
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples", SessionMode=SessionMode.Required,
                 CallbackContract=typeof(ICalculatorDuplexCallback))]
public interface ICalculatorDuplex
{
    [OperationContract(IsOneWay=true)]
    void Clear();
    [OperationContract(IsOneWay = true)]
    void AddTo(double n);
    [OperationContract(IsOneWay = true)]
    void SubtractFrom(double n);
    [OperationContract(IsOneWay = true)]
    void MultiplyBy(double n);
    [OperationContract(IsOneWay = true)]
    void DivideBy(double n);
}
// The callback interface is used to send messages from service back to client.
// The Equals operation will return the current result after each operation.
// The Equation operation will return the complete equation after Clear() is called.
public interface ICalculatorDuplexCallback
{
    [OperationContract(IsOneWay = true)]
    void Equals(double result);
    [OperationContract(IsOneWay = true)]
    void Equation(string eqn);
}
// Service class which implements a duplex service contract.
// Use an InstanceContextMode of PerSession to store the result
// An instance of the service will be bound to each duplex session
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class CalculatorService : ICalculatorDuplex
{
    double result;
    string equation;
    ICalculatorDuplexCallback callback = null;

    public CalculatorService()
    {
        result = 0.0D;
        equation = result.ToString();
        callback = OperationContext.Current.GetCallbackChannel<ICalculatorDuplexCallback>();
    }

    public void Clear()
    {
        callback.Equation(equation + " = " + result.ToString());
        result = 0.0D;
        equation = result.ToString();
    }

    public void AddTo(double n)
    {
        result += n;
        equation += " + " + n.ToString();
        callback.Equals(result);
    }

    public void SubtractFrom(double n)
    {
        result -= n;
        equation += " - " + n.ToString();
        callback.Equals(result);
    }

    public void MultiplyBy(double n)
    {
        result *= n;
        equation += " * " + n.ToString();
        callback.Equals(result);
    }

    public void DivideBy(double n)
    {
        result /= n;
        equation += " / " + n.ToString();
        callback.Equals(result);
    }
}
' Define a duplex service contract.
' A duplex contract consists of two interfaces.
' The primary interface is used to send messages from client to service.
' The callback interface is used to send messages from service back to client.
' ICalculatorDuplex allows one to perform multiple operations on a running result.
' The result is sent back after each operation on the ICalculatorCallback interface.
<ServiceContract(Namespace:="http://Microsoft.ServiceModel.Samples", SessionMode:=SessionMode.Required, _
                CallbackContract:=GetType(ICalculatorDuplexCallback))> _
Public Interface ICalculatorDuplex

    <OperationContract(IsOneWay:=True)> _
    Sub Clear()
    <OperationContract(IsOneWay:=True)> _
    Sub AddTo(ByVal n As Double)
    <OperationContract(IsOneWay:=True)> _
    Sub SubtractFrom(ByVal n As Double)
    <OperationContract(IsOneWay:=True)> _
    Sub MultiplyBy(ByVal n As Double)
    <OperationContract(IsOneWay:=True)> _
    Sub DivideBy(ByVal n As Double)
End Interface

' The callback interface is used to send messages from service back to client.
' The Equals operation will return the current result after each operation.
' The Equation operation will return the complete equation after Clear() is called.
Public Interface ICalculatorDuplexCallback
    <OperationContract(IsOneWay:=True)> _
    Sub Equals(ByVal result As Double)
    <OperationContract(IsOneWay:=True)> _
    Sub Equation(ByVal eqn As String)
end interface

' Service class which implements a duplex service contract.
' Use an InstanceContextMode of PerSession to store the result
' An instance of the service will be bound to each duplex session
<ServiceBehavior(InstanceContextMode:=InstanceContextMode.PerSession)> _
Public Class CalculatorService
    Implements ICalculatorDuplex
    Dim result As Double
    Dim equation As String
    Dim callback As ICalculatorDuplexCallback

    Public Sub New()
        result = 0D
        equation = result.ToString()
        callback = OperationContext.Current.GetCallbackChannel(Of ICalculatorDuplexCallback)()

    End Sub
    Public Sub AddTo(ByVal n As Double) Implements ICalculatorDuplex.AddTo
        result += n
        equation += " + " + n.ToString()
        callback.Equals(result)
    End Sub

    Public Sub Clear() Implements ICalculatorDuplex.Clear
        callback.Equation(equation + " = " + result.ToString())
        result = 0D
        equation = result.ToString()
    End Sub

    Public Sub DivideBy(ByVal n As Double) Implements ICalculatorDuplex.DivideBy
        result /= n
        equation += " / " + n.ToString()
        callback.Equals(result)
    End Sub

    Public Sub MultiplyBy(ByVal n As Double) Implements ICalculatorDuplex.MultiplyBy
        result *= n
        equation += " * " + n.ToString()
        callback.Equals(result)
    End Sub

    Public Sub SubtractFrom(ByVal n As Double) Implements ICalculatorDuplex.SubtractFrom
        result -= n
        equation += " - " + n.ToString()
        callback.Equals(result)
    End Sub
End Class
  • Genom att använda attributen ServiceContractAttribute och OperationContractAttribute kan du automatiskt skapa tjänstkontraktsdefinitioner i WSDL (Web Services Description Language).

  • Använd verktyget ServiceModel Metadata Utility (Svcutil.exe) för att hämta WSDL-dokumentet och (valfri) kod och konfiguration för en klient.

  • Slutpunkter som exponerar duplex-tjänster måste skyddas. När en tjänst tar emot ett duplex-meddelande tittar den på ReplyTo i det inkommande meddelandet för att avgöra var svaret ska skickas. Om kanalen inte är skyddad kan en ej betrodd klient skicka ett skadligt meddelande med måldatorns ReplyTo, vilket leder till en överbelastningsbelastning för måldatorn. Med vanliga begärandesvarsmeddelanden är detta inte ett problem eftersom ReplyTo ignoreras och svaret skickas på kanalen som det ursprungliga meddelandet kom in på.

Se även