Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Windows Communication Foundation (WCF) adalah pilihan yang direkomendasikan dan aman daripada Model Objek Komponen Terdistribusi (DCOM) untuk panggilan kode terkelola antara server dan klien di lingkungan terdistribusi. Artikel ini memperlihatkan cara Anda memigrasikan kode dari DCOM ke WCF untuk skenario berikut.
Layanan jarak jauh mengembalikan objek berdasarkan nilai ke klien
Klien mengirim objek berdasarkan nilai ke layanan jarak jauh
Layanan jarak jauh mengembalikan objek berdasarkan referensi ke klien
Untuk alasan keamanan, mengirim objek berdasarkan referensi dari klien ke layanan tidak diizinkan di WCF. Skenario yang memerlukan percakapan bolak-balik antara klien dan server dapat dicapai di WCF menggunakan layanan dupleks. Untuk informasi selengkapnya tentang layanan dupleks, lihat Layanan Duplex.
Untuk detail selengkapnya tentang membuat layanan dan klien WCF untuk layanan tersebut, lihat Pemrograman WCF Dasar, Merancang dan Menerapkan Layanan, dan Membangun Klien.
Kode contoh DCOM
Untuk skenario ini, antarmuka DCOM yang diilustrasikan menggunakan WCF memiliki struktur berikut:
[ComVisible(true)]
[Guid("AA9C4CDB-55EA-4413-90D2-843F1A49E6E6")]
public interface IRemoteService
{
Customer GetObjectByValue();
IRemoteObject GetObjectByReference();
void SendObjectByValue(Customer customer);
}
[ComVisible(true)]
[Guid("A12C98DE-B6A1-463D-8C24-81E4BBC4351B")]
public interface IRemoteObject
{
}
public class Customer
{
}
Layanan mengembalikan objek berdasarkan nilai
Untuk skenario ini, Anda melakukan panggilan ke layanan dan metode ini mengembalikan objek, yang diteruskan berdasarkan nilai dari server ke klien. Skenario ini mewakili panggilan COM berikut:
public interface IRemoteService
{
Customer GetObjectByValue();
}
Dalam skenario ini, klien menerima salinan objek yang dideserialisasi dari layanan jarak jauh. Klien dapat berinteraksi dengan salinan lokal ini tanpa memanggil kembali ke layanan. Dengan kata lain, klien dijamin layanan tidak akan terlibat dengan cara apa pun ketika metode pada salinan lokal dipanggil. WCF selalu mengembalikan objek dari layanan menurut nilai, sehingga langkah-langkah berikut menjelaskan pembuatan layanan WCF reguler.
Langkah 1: Tentukan antarmuka layanan WCF
Tentukan antarmuka publik untuk layanan WCF dan tandai dengan atribut [ServiceContractAttribute]. Tandai metode yang ingin Anda ekspos ke klien dengan atribut [OperationContractAttribute]. Contoh berikut menunjukkan penggunaan atribut ini untuk mengidentifikasi antarmuka sisi server dan metode antarmuka yang dapat dipanggil klien. Metode yang digunakan untuk skenario ini ditampilkan dalam huruf tebal.
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
. . .
[ServiceContract]
public interface ICustomerManager
{
[OperationContract]
void StoreCustomer(Customer customer);
[OperationContract] Customer GetCustomer(string firstName, string lastName);
}
Langkah 2: Tentukan kontrak data
Selanjutnya Anda harus membuat kontrak data untuk layanan, yang akan menjelaskan bagaimana data akan ditukar antara layanan dan kliennya. Kelas yang dijelaskan dalam kontrak data harus ditandai dengan atribut [DataContractAttribute]. Properti atau bidang individual yang ingin Anda lihat ke klien dan server harus ditandai dengan atribut [DataMemberAttribute]. Jika Anda ingin jenis yang berasal dari kelas dalam kontrak data diizinkan, Anda harus mengidentifikasinya dengan atribut [KnownTypeAttribute]. WCF hanya akan menserialisasikan atau mendeserialisasi jenis dalam antarmuka layanan dan jenis yang diidentifikasi sebagai jenis yang diketahui. Jika Anda mencoba menggunakan jenis yang bukan jenis yang diketahui, pengecualian akan terjadi.
Untuk informasi selengkapnya tentang kontrak data, lihat Kontrak Data.
[DataContract]
[KnownType(typeof(PremiumCustomer))]
public class Customer
{
[DataMember]
public string Firstname;
[DataMember]
public string Lastname;
[DataMember]
public Address DefaultDeliveryAddress;
[DataMember]
public Address DefaultBillingAddress;
}
[DataContract]
public class PremiumCustomer : Customer
{
[DataMember]
public int AccountID;
}
[DataContract]
public class Address
{
[DataMember]
public string Street;
[DataMember]
public string Zipcode;
[DataMember]
public string City;
[DataMember]
public string State;
[DataMember]
public string Country;
}
Langkah 3: Menerapkan layanan WCF
Selanjutnya, Anda harus menerapkan kelas layanan WCF yang mengimplementasikan antarmuka yang Anda tentukan di langkah sebelumnya.
public class CustomerService: ICustomerManager
{
public void StoreCustomer(Customer customer)
{
// write to a database
}
public Customer GetCustomer(string firstName, string lastName)
{
// read from a database
}
}
Langkah 4: Mengonfigurasi layanan dan klien
Untuk menjalankan layanan WCF, Anda perlu mendeklarasikan titik akhir yang mengekspos antarmuka layanan tersebut di URL tertentu menggunakan pengikatan WCF tertentu. Pengikatan menentukan detail transportasi, pengodean, dan protokol bagi klien dan server untuk berkomunikasi. Anda biasanya menambahkan pengikatan ke file konfigurasi proyek layanan (web.config). Berikut ini menunjukkan entri pengikatan untuk layanan eksampel.
<configuration>
<system.serviceModel>
<services>
<service name="Server.CustomerService">
<endpoint address="http://localhost:8083/CustomerManager"
binding="basicHttpBinding"
contract="Shared.ICustomerManager" />
</service>
</services>
</system.serviceModel>
</configuration>
Selanjutnya, Anda perlu mengonfigurasi klien agar sesuai dengan informasi pengikatan yang ditentukan oleh layanan. Untuk melakukannya, tambahkan hal berikut ke file konfigurasi aplikasi klien (app.config).
<configuration>
<system.serviceModel>
<client>
<endpoint name="customermanager"
address="http://localhost:8083/CustomerManager"
binding="basicHttpBinding"
contract="Shared.ICustomerManager"/>
</client>
</system.serviceModel>
</configuration>
Langkah 5: Jalankan layanan
Terakhir, Anda dapat mengelola hosting sendiri dalam aplikasi konsol dengan menambahkan baris kode berikut ke aplikasi layanan. Setelah itu, mulai aplikasi tersebut. Untuk informasi selengkapnya tentang cara lain untuk menghosting aplikasi layanan WCF, Hosting Services.
ServiceHost customerServiceHost = new ServiceHost(typeof(CustomerService));
customerServiceHost.Open();
Langkah 6: Panggil layanan dari klien
Untuk memanggil layanan dari klien, Anda perlu membuat fabrikasi saluran untuk layanan, dan meminta saluran, yang akan memungkinkan Anda langsung memanggil metode GetCustomer dari klien. Saluran ini mengimplementasikan antarmuka layanan dan mengelola logika permintaan/balasan yang mendasar untuk Anda. Nilai pengembalian dari panggilan metode tersebut adalah salinan respons layanan yang dideserialisasi.
ChannelFactory<ICustomerManager> factory =
new ChannelFactory<ICustomerManager>("customermanager");
ICustomerManager service = factory.CreateChannel();
Customer customer = service.GetCustomer("Mary", "Smith");
Klien mengirim objek menurut nilai ke server
Dalam skenario ini, klien mengirim objek ke server, menurut nilai. Ini berarti bahwa server akan menerima salinan objek yang dideserialisasi. Server dapat memanggil metode pada salinan tersebut dan dijamin tidak ada panggilan balik ke dalam kode klien. Seperti disebutkan sebelumnya, pertukaran data WCF normal adalah berdasarkan nilai. Ini menjamin bahwa memanggil metode pada salah satu objek ini hanya dijalankan secara lokal - itu tidak akan memanggil kode pada klien.
Skenario ini mewakili panggilan metode COM berikut:
public interface IRemoteService
{
void SendObjectByValue(Customer customer);
}
Skenario ini menggunakan antarmuka layanan dan kontrak data yang sama seperti yang ditunjukkan dalam contoh pertama. Selain itu, klien dan layanan akan dikonfigurasi dengan cara yang sama. Dalam contoh ini, saluran dibuat untuk mengirim objek dan menjalankan dengan cara yang sama. Namun, untuk contoh ini, Anda akan membuat klien yang memanggil layanan, meneruskan objek berdasarkan nilai. Metode layanan yang akan dipanggil klien dalam kontrak layanan ditampilkan dalam huruf tebal:
[ServiceContract]
public interface ICustomerManager
{
[OperationContract] void StoreCustomer(Customer customer);
[OperationContract]
Customer GetCustomer(string firstName, string lastName);
}
Menambahkan kode ke klien yang mengirim objek menurut nilai
Kode berikut menunjukkan bagaimana klien membuat objek pelanggan berdasarkan nilai baru, membuat saluran untuk berkomunikasi dengan ICustomerManager layanan, dan mengirim objek pelanggan ke dalamnya.
Objek pelanggan akan diserialisasikan dan dikirim ke layanan, di mana layanan tersebut mendeserialisasikannya menjadi salinan baru dari objek tersebut. Metode apa pun yang dipanggil layanan pada objek ini hanya akan dijalankan secara lokal di server. Penting untuk dicatat bahwa kode ini menggambarkan pengiriman jenis turunan (PremiumCustomer). Kontrak layanan mengharapkan Customer objek, tetapi kontrak data layanan menggunakan atribut [KnownTypeAttribute] untuk menunjukkan bahwa PremiumCustomer juga diizinkan. WCF tidak akan dapat menserialisasikan atau mendeserialisasi tipe lain melalui antarmuka layanan ini.
PremiumCustomer customer = new PremiumCustomer();
customer.Firstname = "John";
customer.Lastname = "Doe";
customer.DefaultBillingAddress = new Address();
customer.DefaultBillingAddress.Street = "One Microsoft Way";
customer.DefaultDeliveryAddress = customer.DefaultBillingAddress;
customer.AccountID = 42;
ChannelFactory<ICustomerManager> factory =
new ChannelFactory<ICustomerManager>("customermanager");
ICustomerManager customerManager = factory.CreateChannel();
customerManager.StoreCustomer(customer);
Layanan mengembalikan objek berdasarkan referensi
Untuk skenario ini, aplikasi klien melakukan panggilan ke layanan jarak jauh dan metode mengembalikan objek, yang diteruskan oleh referensi dari layanan ke klien.
Seperti disebutkan sebelumnya, layanan WCF selalu mengembalikan objek berdasarkan nilai. Namun, Anda dapat mencapai hasil yang sama dengan menggunakan EndpointAddress10 kelas . EndpointAddress10 adalah objek by-value yang dapat diserialisasikan dan dapat digunakan oleh klien untuk mendapatkan objek by-reference yang memiliki sesi di server.
Perilaku objek referensi demi referensi dalam WCF yang ditunjukkan dalam skenario ini berbeda dari DCOM. Di DCOM, server dapat mengembalikan objek referensi secara langsung ke klien, dan klien dapat memanggil metode objek tersebut, yang dijalankan di server. Namun, di WCF, objek yang dikembalikan selalu berdasarkan nilai. Klien harus mengambil objek berdasarkan nilai tersebut, yang diwakili oleh EndpointAddress10 dan menggunakannya untuk membuat objek referensi berdasarkan sesinya sendiri. Metode klien memanggil objek sesi yang dijalankan di server. Dengan kata lain, objek by-reference di WCF ini adalah layanan WCF normal yang dikonfigurasi untuk memiliki sesi.
Di WCF, sesi adalah cara untuk menghubungkan beberapa pesan yang dikirim di antara dua titik akhir. Ini berarti bahwa setelah klien mendapatkan koneksi ke layanan ini, sesi akan dibuat antara klien dan server. Klien akan menggunakan satu instans unik objek sisi server untuk semua interaksinya dalam satu sesi ini. Kontrak WCF yang memiliki sesi mirip dengan pola permintaan/respons jaringan berorientasi koneksi.
Skenario ini diwakili oleh metode DCOM berikut.
public interface IRemoteService
{
IRemoteObject GetObjectByReference();
}
Langkah 1: Tentukan antarmuka dan implementasi layanan WCF Yang Penuh Sesi
Pertama, tentukan antarmuka layanan WCF yang berisi objek sesi.
Dalam kode ini, objek sesi ditandai dengan ServiceContract atribut , yang mengidentifikasinya sebagai antarmuka layanan WCF biasa. Selain itu, properti SessionMode diatur untuk menunjukkan bahwa itu akan menjadi layanan yang menggunakan sesi.
[ServiceContract(SessionMode = SessionMode.Allowed)]
public interface ISessionBoundObject
{
[OperationContract]
string GetCurrentValue();
[OperationContract]
void SetCurrentValue(string value);
}
Kode berikut menunjukkan implementasi layanan.
Layanan ini ditandai dengan atribut [ServiceBehavior], dan properti InstanceContextMode-nya diatur ke InstanceContextMode.PerSessions untuk menunjukkan bahwa instans unik jenis ini harus dibuat untuk setiap sesi.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class MySessionBoundObject : ISessionBoundObject
{
private string _value;
public string GetCurrentValue()
{
return _value;
}
public void SetCurrentValue(string val)
{
_value = val;
}
}
Langkah 2: Tentukan layanan fabrikasi WCF untuk objek yang menyimpan sesi
Layanan yang membuat objek sesi harus ditentukan dan diimplementasikan. Kode berikut menunjukkan cara melakukannya. Kode ini membuat layanan WCF lain yang mengembalikan EndpointAddress10 objek. Ini adalah bentuk titik akhir yang dapat diserialisasikan yang dapat digunakan untuk membuat objek penuh sesi.
[ServiceContract]
public interface ISessionBoundFactory
{
[OperationContract]
EndpointAddress10 GetInstanceAddress();
}
Berikut ini adalah implementasi layanan ini. Implementasi ini mempertahankan pabrik saluran singleton untuk membuat objek yang mendukung sesi. Ketika GetInstanceAddress dipanggil, ia membuat saluran dan membuat EndpointAddress10 objek yang menunjuk ke alamat jarak jauh yang terkait dengan saluran ini.
EndpointAddress10 adalah jenis data yang dapat dikembalikan ke klien menurut nilai.
public class SessionBoundFactory : ISessionBoundFactory
{
public static ChannelFactory<ISessionBoundObject> _factory =
new ChannelFactory<ISessionBoundObject>("sessionbound");
public SessionBoundFactory()
{
}
public EndpointAddress10 GetInstanceAddress()
{
IClientChannel channel = (IClientChannel)_factory.CreateChannel();
return EndpointAddress10.FromEndpointAddress(channel.RemoteAddress);
}
}
Langkah 3: Mengonfigurasi dan memulai layanan WCF
Untuk menghosting layanan ini, Anda harus membuat tambahan berikut ke file konfigurasi server (web.config).
<client>Tambahkan bagian yang menjelaskan titik akhir untuk objek sesi. Dalam skenario ini, server juga bertindak sebagai klien dan harus dikonfigurasi untuk mengaktifkan ini.Di bagian
<services>, nyatakan titik akhir layanan untuk pabrik dan objek berbasis sesi. Ini memungkinkan klien untuk berkomunikasi dengan titik akhir layanan, memperoleh EndpointAddress10 dan membuat saluran sesi.
Berikut ini adalah contoh file konfigurasi dengan pengaturan ini:
<configuration>
<system.serviceModel>
<client>
<endpoint name="sessionbound"
address="net.tcp://localhost:8081/SessionBoundObject"
binding="netTcpBinding"
contract="Shared.ISessionBoundObject"/>
</client>
<services>
<service name="Server.MySessionBoundObject">
<endpoint address="net.tcp://localhost:8081/SessionBoundObject"
binding="netTcpBinding"
contract="Shared.ISessionBoundObject" />
</service>
<service name="Server.SessionBoundFactory">
<endpoint address="net.tcp://localhost:8081/SessionBoundFactory"
binding="netTcpBinding"
contract="Shared.ISessionBoundFactory" />
</service>
</services>
</system.serviceModel>
</configuration>
Tambahkan baris berikut ke aplikasi konsol, untuk menghost sendiri layanan, dan memulai aplikasi.
ServiceHost factoryHost = new ServiceHost(typeof(SessionBoundFactory));
factoryHost.Open();
ServiceHost sessionBoundServiceHost = new ServiceHost(
typeof(MySessionBoundObject));
sessionBoundServiceHost.Open();
Langkah 4: Mengonfigurasi klien dan memanggil layanan
Konfigurasikan klien untuk berkomunikasi dengan layanan WCF dengan membuat entri berikut dalam file konfigurasi aplikasi proyek (app.config).
<configuration>
<system.serviceModel>
<client>
<endpoint name="sessionbound"
address="net.tcp://localhost:8081/SessionBoundObject"
binding="netTcpBinding"
contract="Shared.ISessionBoundObject"/>
<endpoint name="factory"
address="net.tcp://localhost:8081/SessionBoundFactory"
binding="netTcpBinding"
contract="Shared.ISessionBoundFactory"/>
</client>
</system.serviceModel>
</configuration>
Untuk memanggil layanan, tambahkan kode ke klien untuk melakukan hal berikut:
Buat saluran ke layanan
ISessionBoundFactory.Gunakan saluran untuk memanggil layanan
ISessionBoundFactorydan untuk mendapatkan objek EndpointAddress10.Gunakan EndpointAddress10 untuk membuat saluran yang memperoleh objek berbasis sesi.
Panggil metode
SetCurrentValuedanGetCurrentValueuntuk menunjukkan bahwa instans objek yang sama digunakan dalam beberapa panggilan.
ChannelFactory<ISessionBoundFactory> factory =
new ChannelFactory<ISessionBoundFactory>("factory");
ISessionBoundFactory sessionBoundFactory = factory.CreateChannel();
EndpointAddress10 address = sessionBoundFactory.GetInstanceAddress();
ChannelFactory<ISessionBoundObject> sessionBoundObjectFactory =
new ChannelFactory<ISessionBoundObject>(
new NetTcpBinding(),
address.ToEndpointAddress());
ISessionBoundObject sessionBoundObject =
sessionBoundObjectFactory.CreateChannel();
sessionBoundObject.SetCurrentValue("Hello");
if (sessionBoundObject.GetCurrentValue() == "Hello")
{
Console.WriteLine("Session-full instance management works as expected");
}
Baca juga
- Pemrograman WCF Dasar
- Merancang dan Menerapkan Layanan
- Membangun Klien
- Layanan Dupleks