Routing dapat diumpamakan sebagai front end service yang menghubungkan antara client dan back end service. Filtering dilakukan dengan identifikasi konten dari message yang dikirim dari client dimana data yang akan difilter disimpan di file konfigurasi. Terdapat beberapa jenis filter yang dapat digunakan untuk mengidentifikasikan konten dari message yang dikirim oleh client, jenis filter tersebut diantaranya adalah :
Fokus pada posting kali ini yaitu penggunaan Action sebagai jenis filter yang akan digunakan untuk melakukan filtering message berdasarkan method atau operation yang di request oleh client.
Contoh routing yang dibuat dilakukan di localhost komputer dengan hanya mengubah port yang digunakan sebagai hasil routing. Tentunya ini hanya sebagai contoh, dan di real world nya routing tersebut dapat ditujukan ke server yang berbeda satu sama lain antara service dengan service lainnya.
1. Asumsikan di dalam contract terdapat operation dan data contract berikut :
Namespace properti yang terdapat di dalam atribut ServiceContract digunakan untuk memodifikasi action message agar mudah untuk diidentifikasi di filter data, begitu juga dengan penggunaan Name properti di atribut OperationContract.
2. Implementasi contract tersebut di service implementation tidak ada yang istimewa, hanya berupa data logic yang mengambil dan melakukan insert data ke tabel Northwind. Anda dapat melakukannya dengan teknik data access yang telah disediakan di .NET framework. Untuk mendapatkan informasi tentang routing yang terjadi pada saat request dan reply terhadap operation yang di request digunakan message inspector yang dibuat dengan membuat class-class yang mengimplementasikan interface-interface IDispatchMessageInspector, IServiceBehaviour dan class yang diturunkan dari class BehaviorExtensionElement. Saya tidak akan menjelaskan tentang pembuatan class-class tersebut. Tentunya kita hanya akan fokus terhadap penggunaan RoutingService.
3. Asumsikan di file configuration yang terdapat di dalam project service host terdapat setting service sebagai berikut :
<services>
<service name="NorthwindService.NorthwindService">
<endpoint address="http://localhost:1234/NorthwindService"
binding="basicHttpBinding"
contract="NorthwindContract.INorthwind"
name="NorthwindEndpoint1" />
<endpoint address="http://localhost:1235/NorthwindService"
binding="basicHttpBinding"
contract="NorthwindContract.INorthwind"
name="NorthwindEndpoint2" />
</service>
</services>
Host tersebut menyediakan dua buah endpoint dengan address yang berbeda. Tentunya didalam aplikasi yang riil setiap endpoint tersebut dapat merujuk ke server yang berbeda untuk setiap endpointnya.
4. Ketikkan kode berikut ini di project yang digunakan sebagai routing service. Project yang digunakan sebagai routing service saya buat dalam sebuah aplikasi console :
1: Imports System.ServiceModel
2: Imports System.ServiceModel.Routing
3:
4: Module Module1
5:
6: Sub Main()
7: Dim router As New ServiceHost(GetType(RoutingService))
8: Try
9: Console.WriteLine("Routing Service is start.")
10: router.Open()
11: Console.WriteLine("Routing Service is running.")
12: Console.WriteLine("Press ENTER to stop the routing service")
13: Console.ReadLine()
14: router.Close()
15: Catch ex As Exception
16: If router IsNot Nothing Then router.Close()
17: Console.WriteLine(ex.Message)
18: End Try
19: End Sub
20:
21: End Module
Perhatikan kode pada baris ke 7. Untuk mengimplementasikan routing service di wcf 4.0 cukup mudah sekali, tidak ada perbedaan dengan kode yang dibuat untuk membuat host di aplikasi console yang serupa. Disini kita cukup menghosting RoutingService class.
5. Tambahkan service behavior berikut ini di project routing service (setting tersebut dapat dilakukan dengan menggunakan wcf service configuration editor) :
<behaviors>
<serviceBehaviors>
<behavior name="">
<routing routeOnHeadersOnly="true"
filterTableName="NorthwindRoutingTable"
soapProcessingEnabled="false" />
</behavior>
</serviceBehaviors>
</behaviors>
Behaviour tersebut digunakan untuk melakukan setting routing diantaranya ialah nama filter tabel yang akan digunakan untuk melakukan message filtering, routing hanya digunakan untuk mengidentifikasikan action message di header, dan format data tidak dapat diubah selama proses request dan response (soapProcessingEnabled=false).
6. Buat client endpoint berikut ini di project routing service :
<client>
<endpoint address="http://localhost:1234/NorthwindService"
binding="basicHttpBinding"
contract="*"
name="NorthwindRoute1"/>
<endpoint address="http://localhost:1235/NorthwindService"
binding="basicHttpBinding"
contract="*"
name="NorthwindRoute2"/>
</client>
Bandingkan endpoint tersebut dengan endpoint yang terdapat di langkah-3. Address dan binding yang digunakan harus sama dengan setting yang di definisikan di wcf service host. Semua contract yang terdapat di dalam service implementation tersebut akan digunakan sebagai object message filtering.
7. Tambahkan service baru di file configuration yang sama :
<services>
<service name="System.ServiceModel.Routing.RoutingService">
<endpoint address="http://localhost:1236/NorthwindRouting"
binding="basicHttpBinding"
contract="System.ServiceModel.Routing.IRequestReplyRouter"/>
</service>
</services>
Endpoint tersebut merupakan endpoint untuk routing service yang nantinya akan digunakan oleh aplikasi client. Contract yang digunakan tergantung dari Messaging Pattern yang akan digunakan. Terdapat beberapa jenis contract yang berhubungan dengan routing service diantaranya adalah sbb :
- IDuplexSessionRouter
- IRequestReplyRouter
- ISimplexDatagramRouter
- ISimplexSessionRouter
Pada contoh kali ini messaging pattern yang digunakan yaitu Request and Reply. Untuk merujuk ke contract tersebut anda cukup browse ke assembly System.ServiceMode.Routing.dll lewat GAC tab yang terdapat di kotak dialog pada saat melakukan penambahan service di atas.
8. Tambahkan routing elemen berikut ini di file configuration yang sama di project routing service :
<routing>
<filters>
<filter name="GetCustomers"
filterType="Action"
filterData="http://native-enterprise.net/NativeCustomer/GetNorthwindData"/>
<filter name="AddCustomer"
filterType="Action"
filterData="http://native-enterprise.net/NativeCustomer/AddNorthwindData"/>
</filters>
<filterTables>
<filterTable name="NorthwindRoutingTable">
<add filterName="GetCustomers"
endpointName="NorthwindRoute1"/>
<add filterName="AddCustomer"
endpointName="NorthwindRoute1"/>
</filterTable>
</filterTables>
</routing>
Elemen filters berisi jenis filter yang digunakan untuk melakukan filtering data yang terdapat di dalam action header yang di request oleh client. Perhatikan nilai dari filterData properti diatas, bandingkan dengan penggunaan namespace dan name properti di ServiceContract atribut yang digabungkan dengan name properti yang terdapat di dalam atribut OperationContract. Data itulah yang digunakan untuk mengidentifikasikan action yang di request oleh client dimana informasi tersebut terdapat di dalam header soap envelope.
Untuk melakukan routing kedua filterData tersebut diatas maka dibuatkan filterTable dengan nama yang harus sama dengan yang telah didefinisikan sebelumnya (perhatikan langkah-5). Di dalam elemen filterTable tersebut filterData yang telah didefinisikan berdasarkan name nya akan di route berdasarkan nilai yang diberikan di atribut endpointName dimana addressnya sudah di atur di langkah-6.
9. Buat sebuah aplikasi client yang akan digunakan untuk memanggil method-method yang terdapat di dalam wcf service. Pada contoh ini saya akan membuat sebuah aplikasi windows form yang sederhana dimana di dalam form tersebut terdapat dua buah button dan satu buah kontrol DataGridView.

10. Tambahkan referensi terhadap assembly contract project yang telah dibuat dan assembly System.ServiceModel.dll kedalam project tersebut.
11. Ketikkan kode berikut ini di dalam form yang telah dibuat sebelumnya :
1: Imports System.ServiceModel
2:
3: Public Class Form1
4:
5: Private Sub btnGetCustomers_Click() Handles btnGetCustomers.Click
6: Dim strRouteUrl = "http://localhost:1236/NorthwindRouting"
7: Dim aBinding = New BasicHttpBinding
8:
9: Dim cf = New ChannelFactory(Of NorthwindContract.INorthwind)(
10: aBinding, strRouteUrl)
11:
12: Dim aChannel = cf.CreateChannel
13:
14: Dim customers = aChannel.GetCustomers
15: DataGridView1.DataSource = customers.ToList
16: End Sub
17:
18: Private Sub btnAddCustomer_Click() Handles btnAddCustomer.Click
19: Dim strRouteUrl = "http://localhost:1236/NorthwindRouting"
20: Dim aBinding = New BasicHttpBinding
21:
22: Dim cf = New ChannelFactory(Of NorthwindContract.INorthwind)(
23: aBinding, strRouteUrl)
24:
25: Dim aChannel = cf.CreateChannel
26:
27: aChannel.AddCustomer(New NorthwindContract.CustomerData With {
28: .CustomerID = "NTV",
29: .CompanyName = "Native Enterprise"})
30: End Sub
31:
32: End Class
Perhatikan kode pada baris-6, endpoint yang dituju merupakan endpoint dari project routing service yang telah dibuat sebelumnya (perhatikan langkah-7). Untuk melakukan komunikasi dengan project routing service digunakan ChannelFactory class yang dapat membaca contract dan service implementation secara dinamis, sehingga disini kita tidak perlu lagi melakukan service reference terhadap wcf service yang akan digunakan.
12. Jalankan semua project tersebut diatas secara multiple startup dengan urutan Project routing service, project service host dan project wcf client. Hasilnya dapat dilihat di gambar berikut ini :

Pada saat tombol Get Customers di klik maka message akan di route ke endpoint address http://localhost:1234/NorthwindService :

Begitu juga pada saat tombol Add Customer di klik maka message akan di route ke endpoint address http://localhost:1235/NorthwindService :

Dari gambar di atas dapat dilihat bahwa message yang di request oleh client akan di route berdasarkan filterData yang telah di definisikan di filter table. Ok…selamat mencoba :)