Nasıl yapılır: Çift Yönlü Sözleşme Oluşturma
Bu konu başlığında çift yönlü (çift yönlü) anlaşma kullanan yöntemler oluşturmanın temel adımları gösterilmektedir. Çift yönlü anlaşma, istemcilerin ve sunucuların birbirleriyle bağımsız olarak iletişim kurmasına olanak tanır, böylece diğeriyle çağrı başlatılabilir. Çift yönlü sözleşme, Windows Communication Foundation (WCF) hizmetlerinde kullanılabilen üç ileti desenlerinden biridir. Diğer iki ileti deseni tek yönlü ve istek-yanıt şeklindedir. Çift yönlü sözleşme, istemci ile sunucu arasındaki iki tek yönlü sözleşmeden oluşur ve yöntem çağrılarının bağıntılı olmasını gerektirmez. Hizmetinizin daha fazla bilgi için istemciyi sorgulaması veya istemcide açıkça olay oluşturması gerektiğinde bu tür bir sözleşme kullanın. Çift yönlü anlaşma için istemci uygulaması oluşturma hakkında daha fazla bilgi için bkz. Nasıl yapılır: Çift Yönlü Sözleşme ile Access Hizmetleri. Çalışan bir örnek için çift yönlü örneğe bakın.
Çift yönlü sözleşme oluşturmak için
Çift yönlü sözleşmenin sunucu tarafını oluşturan arabirimi oluşturun.
sınıfını ServiceContractAttribute arabirime uygulayın.
[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
Arabirimde yöntem imzalarını bildirin.
Sınıfı, OperationContractAttribute ortak sözleşmenin parçası olması gereken her yöntem imzasına uygulayın.
Hizmetin istemcide çağırabileceği işlem kümesini tanımlayan geri çağırma arabirimini oluşturun.
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
Geri çağırma arabiriminde yöntem imzalarını bildirin.
Sınıfı, OperationContractAttribute ortak sözleşmenin parçası olması gereken her yöntem imzasına uygulayın.
Birincil arabirimdeki özelliğini geri çağırma arabiriminin türüne CallbackContract ayarlayarak iki arabirimi çift yönlü bir sözleşmeye bağlayın.
İstemcide yöntemleri çağırmak için
Hizmetin birincil sözleşmeyi uygulamasına geri çağırma arabirimi için bir değişken bildirin.
değişkenini sınıfının yöntemi tarafından GetCallbackChannel döndürülen nesne başvurusuna OperationContext ayarlayın.
ICalculatorDuplexCallback callback = null;
Dim callback As ICalculatorDuplexCallback
callback = OperationContext.Current.GetCallbackChannel<ICalculatorDuplexCallback>();
callback = OperationContext.Current.GetCallbackChannel(Of ICalculatorDuplexCallback)()
Geri çağırma arabirimi tarafından tanımlanan yöntemleri çağırın.
Örnek
Aşağıdaki kod örneği çift yönlü iletişimi gösterir. Hizmetin sözleşmesi ileri ve geri gitmek için hizmet işlemlerini içerir. İstemcinin sözleşmesi, konumunu raporlamaya yönelik bir hizmet işlemi içerir.
// 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
ServiceContractAttribute ve OperationContractAttribute özniteliklerinin uygulanması, Web Hizmetleri Açıklama Dili'nde (WSDL) hizmet sözleşmesi tanımlarının otomatik olarak oluşturulmasına olanak tanır.
İstemcinin WSDL belgesini ve (isteğe bağlı) kodunu ve yapılandırmasını almak için ServiceModel Meta Veri Yardımcı Programı Aracı'nı (Svcutil.exe) kullanın.
Çift yönlü hizmetleri ortaya çıkarmak için uç noktaların güvenliği sağlanmalıdır. Bir hizmet çift yönlü bir ileti aldığında, yanıtın nereye gönderileceğini belirlemek için bu gelen iletideki Yanıtla'ya bakar. Kanal güvenli değilse, güvenilmeyen bir istemci hedef makinenin ReplyTo değeriyle kötü amaçlı bir ileti gönderebilir ve bu da hedef makinenin hizmet reddine yol açabilir. Normal istek-yanıt iletilerinde bu bir sorun değildir, çünkü Yanıtla yoksayılır ve yanıt özgün iletinin geldiği kanala gönderilir.