Cara: Membuat Kontrak Dupleks
Topik ini menunjukkan langkah-langkah dasar untuk membuat metode yang menggunakan kontrak dupleks (dua arah). Kontrak dupleks memungkinkan klien dan server untuk berkomunikasi satu sama lain secara independen sehingga dapat memulai panggilan ke yang lain. Kontrak dupleks adalah salah satu dari tiga pola pesan yang tersedia untuk layanan Windows Communication Foundation (WCF). Dua pola pesan lainnya adalah satu arah dan balasan permintaan. Kontrak dupleks terdiri dari dua kontrak satu arah antara klien dan server dan tidak mengharuskan panggilan metode berkorelasi. Gunakan kontrak semacam ini saat layanan Anda harus meminta klien informasi selengkapnya atau secara eksplisit mengajukan peristiwa pada klien. Untuk informasi selengkapnya tentang membuat aplikasi klien untuk kontrak dupleks, lihat Cara: Layanan Access dengan Kontrak Dupleks. Untuk sampel yang berfungsi, lihat sampel Dupleks.
Untuk membuat kontrak dupleks
Buat antarmuka yang membentuk sisi server kontrak dupleks.
Terapkan kelas ServiceContractAttribute ke antarmuka.
[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
Nyatakan tanda tangan metode di antarmuka.
Terapkan kelas OperationContractAttribute ke setiap taexception.Innda tangan metode yang harus menjadi bagian dari kontrak publik.
Buat antarmuka panggilan balik yang menentukan serangkaian operasi layanan yang dapat memanggil klien.
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
Nyatakan tanda tangan metode di antarmuka panggilan balik.
Terapkan kelas OperationContractAttribute ke setiap taexception.Innda tangan metode yang harus menjadi bagian dari kontrak publik.
Tautkan dua antarmuka ke dalam kontrak dupleks dengan mengatur properti CallbackContract di antarmuka utama ke jenis antarmuka panggilan balik.
Untuk memanggil metode pada klien
Dalam implementasi layanan kontrak utama, nyatakan variabel untuk antarmuka panggilan balik.
Atur variabel ke referensi objek yang dikembalikan oleh metode GetCallbackChannel dari kelas OperationContext.
ICalculatorDuplexCallback callback = null;
Dim callback As ICalculatorDuplexCallback
callback = OperationContext.Current.GetCallbackChannel<ICalculatorDuplexCallback>();
callback = OperationContext.Current.GetCallbackChannel(Of ICalculatorDuplexCallback)()
Panggil metode yang ditentukan oleh antarmuka panggilan balik.
Contoh
Contoh kode berikut menunjukkan komunikasi dupleks. Kontrak layanan berisi operasi layanan untuk bergerak maju dan mundur. Kontrak klien berisi operasi layanan untuk melaporkan posisinya.
// 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
Menerapkan atribut ServiceContractAttribute dan OperationContractAttribute memungkinkan pembuatan otomatis definisi kontrak layanan dalam Bahasa Deskripsi Layanan Web (WSDL).
Gunakan ServiceModel Metadata Utility Tool (Svcutil.exe) untuk mengambil konfigurasi dan kode (opsional) dan dokumen WSDL untuk klien.
Titik akhir yang mengekspos layanan dupleks harus diamankan. Saat layanan menerima pesan dupleks, terlihat ReplyTo dalam pesan masuk tersebut untuk menentukan tempat mengirim balasan. Jika saluran tidak diamankan, maka klien yang tidak tepercaya dapat mengirim pesan berbahaya dengan ReplyTo komputer target, yang mengarah ke penolakan layanan mesin target. Dengan pesan balasan permintaan reguler, hal ini bukan masalah, karena ReplyTo diabaikan dan respons dikirim di saluran tempat pesan asli masuk.