iki veya daha fazla masaüstü uygulamasını konuşturma – WCF

Note: Yazi Burak Selim Senyurt‘a aittir, ustune anlamadigim ve ogrenip yaptigim birkac cumle ekledim.

Windows Communication Foundation mimarisinin geliştirilmesininin tek amacı, var olan dağıtık mimari modellerini bir çatı altında birleştirmek değildir. Buna paralel olaraktan WCF mimarisi, .Net Remoting, Xml Web Servisleri, WSE(Web Service Enhancements), MSMQ(Microsoft Message Queue), COM+ gibi pek çok dağıtık uygulama geliştirme modelinin çalışma zamanı alt yapısının kolayca oluşturulabilmesinide hedeflemektedir. Burada dekleratif programlama modelinin benimsenmesinin önemli katkısı vardır. Sonuçta geliştiricinin sıklıkla yapmak zorunda kaldığı alt yapı hazırlıklarının  attribute(nitelik) veya konfigurasyon bazlı olacak şekilde ayarlanabilmesi son derece avantajlıdır. Bu açıdan bakıldığında olayın kilit noktası WCF in ABC(AddressBindingContract) sinde yer alan bağlayıcı tiplerdir(Binding Types). Bilindiği üzere WCF mimarisi .Net Framework 3.0 ile birlikte gelmiştir. Bununla birlikte şu an itibariyle .Net Framework 3.5 sürümünde ek yeniliklerde içermektedir(Örneğin Web Programlama Modeli, WorkFlow Foundation ile Tam Entegrasyon, JSON, AJAX desteği gibi). Bağlayıcı tiplerin sayısının çok olmasının, geliştiricilerin karar verme noktasındaki işlerini zorlaştırdığıda bir gerçektir. Bu nedenle çoğunlukla yardımcı tablolardan veya diagramlardan yararlanılmaktadır.

Yazın geldiği bu sıcak günlerde yazdığımız bu makalemizde, biraz hafiften ilerleyecek ve bu bağlayıcı tiplerden çok sık kullanılanlar arasındaki performans farklarını incelemek için nasıl bir yol izleyebileceğimizi incelemeye çalışacağız. Nitekim senaryoya göre seçilebilecek bağlayıcı tiplerin birden fazla olması halinde performans kriterleri ön plana çıkmaktadır. Öncelikli olarak şu anda kullanılan bağlayıcı tipler ve aralarındaki belirgin farklıları göz önüne almakta yarar vardır. İşte aşağıdaki tablo bu farklılıkları dile getirmektedir.

Görüldüğü gibi bağlayıcı tiplerin birbirlerine göre farklı kullanım sahaları ve senaryoları bulunmaktadır. Buradaki bağlayıcı tiplerde yeterli gelmiyorsa bu durumda özel bağlayıcı tiplerin(Custom Binding Type) yazılmasıda tercih edilebilir ki bazı senaryolarda(örneğin Front-End Service yazılması gereken durumlar veya Reply Attack gibi vakalarda) bu gereklidir. Yukarıdaki tablo karar vermek için tam olarak yeterli değildir. Karar verirken ele alınması gereken sorular arasında platform bağımsızlık(Interoperability), güvenilirlik(Relaibiliyu), performans, WS-* şartnameleri(Specifications), güvenlik(Security) gibi pek çok kriter bulunmaktadır. İşte bu noktada da devreye aşağıdaki gibi bir tablo girmektedir.

Görüldüğü gibi bu tabloda yer alan kriterlerden yararlanarak hangi bağlayıcı tipin kullanılacağı kolay bir şekilde kararlaştırılabilir. Söz gelimi çift yönlü(Duplex) iletişimin söz konusu olduğu bir vaka varsa, kriterler sınırlıdır. Bir başka deyişle böyle bir senaryoda WsDualHttpBinding, NetTcpBinding, NetNamedPipeBinding ve NetPeerTcpBinding tiplerinden birisi kullanılabilir. Ancak karar vermek halen daha zor olabilmektedir. Belkide bir başlangıç noktası olsa bu iş daha da kolaylaşabilir. O halde bir akış şeması son derece yerinde olur. Mesela;

Öncelikli olarak başka servisler ile uyumlu bir şekilde konuşulup konuşulmayacağına karar verilerek başlayan bu iş akışının farklı versiyonlarıda bulunmaktadır. Ancak Juval Löwy ve Steve Resnic’ in önerdiği örnek karar verme adımlarından biriside bu çizelgedir. Karar vermede önemli olan kriterlerden biriside elbetteki Performans’ tır. Çoğunlukla gerçek hayat ortamlarında, yazılan uygulamaların gerçek değeri performansları ile ölçülmektedir. Bu durumda akla gelen sorulardan ilki vakaya göre hangi bağlayıcı tipin en iyi performansı verdiğidir. İşte yazımızın bu bölümünden itibaren 4 temel ve sık kullanılan bağlayıcı tip arasındaki saniye başına düşen çağrı(Calls Per Seconds) sayılarını test edeceğimiz örnek bir senaryo üzerinde durmaya çalışacağız. Vakamızda NetTcpBinding, WsHttpBinding, BasicHttpBinding ve NetNamedPipeBinding bağlayıcı tipleri ele alınmaktadır.

Bilindiği üzere NetTcpBinding bağlayıcı tipi çoğunlukla intranet tabanlı sistemlerde yüksek performansı ile göz önüne çıkmaktadır. Ne varki WS destekli servisler ile konuşulması gereken vakalarda WsHttpBinding bağlayıcı tipi sıkılıkla değerlendirilmektedir. Tüm bunların yanında özellikle WS Basic Profile 1.1 ve öncesi yazılmış Web Servisleri ile olan haberleşmede BasicHttpBinding biçilmiş kaftandır. Elbette öyle vakalar vardırki aynı makine üzerinde koşmakta olan servislerin bir birleriyle haberleşmesi söz konusudur. Çok doğal olarak böyle bir durumda NetNamedPipeBinding tipi ön tarafa çıkmaktadır.

1.   UYGULAMA

Öncelikli olarak kendimize bir adet WCF Servis Library geliştiriyor olacağız. (Söz konusu servis kütüphanesi Visual Studio 2008 kullanılarak .Net Framework 3.5 şablonunda geliştirilmiştir.) Servis tarafına sunulacak olan sözleşme(Contract) ve uygulayıcı tipin içeriği aşağıdaki gibidir.

Visual Studio 2008 de ProcessLib adinda Class Library projesi olusturuyoruz, buna dikkat edelim, yoksa benim gibi Console Application yaratip, dll dosyasini arayip durursunuz J Burda ogrendigim bir tricki söylemek istiyorum, Tester sinifini direk veya manuel yarattiktan sonra diagram da sag tiklayip direk Interface i oluşturabilirsiniz.

using System;
using System.ServiceModel;
namespace ProcessLib
{
[ServiceContract]
public interface ITester
{
[OperationContract]
int topla(int a, int b);
}
}

using System;
namespace ProcessLib
{
public class Tester:ITester
{
#region ITester Members
public int topla(int a, int b)
{
return a+b;
}
#endregion
}
}

Şimdi bir tane de Console Uygulamasi yaratiyoruz, adina da ServerApp diyelim. Solution Explorer a bakarsaniz app.config I goremiceksiniz. Projeye sag tiklayip, add->new item->application configuration file direk ekliyoruz. Sonra aşagidaki configi yapiştirin.


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="ProcessLib.Tester">
<endpoint address="net.pipe://localhost/TesterService" binding="netNamedPipeBinding" bindingConfiguration="" name="TesterServicePipeEndPoint" contract="ProcessLib.ITester" />
</service>
</services>
</system.serviceModel>
</configuration>

Program.cs icine direk aşağidaki kodu ekleyebilirsiniz. Bu kod server gorevini goruyor.

using System;
using System.ServiceModel;
using ProcessLib;
namespace ServerApp
{
class Program
{
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(Tester));
host.Opening += delegate(object sender, EventArgs e)
{
Console.WriteLine("Servis açılıyor...");
};
// Servis açıldıktan sonraki event metodu
host.Opened += delegate(object sender, EventArgs e)
{
Console.WriteLine("Servis açıldı...");
};
// Servis kapanırkenki event metodu
host.Closing += delegate(object sender, EventArgs e)
{
Console.WriteLine("Servis kapanıyor...");
};
// Servis kapandığındaki event metodu
host.Closed += delegate(object sender, EventArgs e)
{
Console.WriteLine("Servis kapandı...");
};
try
{
host.Open();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
throw;
}
Console.WriteLine("Servis dinlemede\nKapatmak için bir tuşa basın");
Console.ReadLine();
try
{
host.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
throw;
}
}
}
}

Host uygulama 1 EndPoint üzerinden hizmet vermektedir. EndPoint Tester isimli servis tipini kullanmaktadır. İstemci tarafını geliştirmeden önce gerekli proxy tipinin üretimi için svcutil* aracından aşağıdaki ekran görüntüsünde yer aldığı gibi yararlanılabilir. Bu proxy, normal bildigimiz browser uzerinden yasaklanmis bir siteye girmek icin kullandigimiz bir proxy degil. Burdaki proxy, applicationlarin birbirleriyle nasil konuşacaklarini gösteren yol. Burda olusturulan TesterProxy.cs dosyasini diger application yazacak olan arkadaslara veriyoruz, boylece onlar bu cs dosyasi uzerinden bizim sunmus oldugumuz fonksiyonlara erişebiliyorlar.

Artık istemci uygulamanın geliştirilmesine başlanabilir. Buradada örneği basit bir şekilde ele alabilmek için bir Console uygulaması göz önüne alınmaktadır. ClientApp adinda bir console uygulamasi yaratin. Yine manuel olarak app.config dosyasini ekleyin ve aşağıdaki kodlari ilgili yerlere yapiştirin. Yine önemli olan nokta konfigurasyon dosyasının içeriğidir.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<client>
<endpoint address="net.pipe://localhost/TesterService" binding="netNamedPipeBinding" bindingConfiguration="" contract="ITester" name="ClientPipeEndPoint" />
</client>
</system.serviceModel>
</configuration>


using System;
namespace ClientApp
{
class Program
{
static void Main(string[] args)
{
int a = 0, b = 0;
TesterClient client = new TesterClient("ClientPipeEndPoint");
while (true)
{
Console.WriteLine("Bir sayi girin: ");
a = Int32.Parse(Console.ReadLine());
Console.WriteLine("Bir sayi girin: ");
b = Int32.Parse(Console.ReadLine());
Console.WriteLine("Toplam: " + client.topla(a, b));
}
}
}
}

Bundan sonra yapmaniz gereken uygulamalari çalıştırmak. İlk once AppServer uygulamamizi calistiralim. Sonra client uygulamamiz ile test edebiliriz.

Not*: svcutil direk command promtta çalışmıyor. Bu yuzden Visual Studio uzerinde olusturacağimiz kisayol ile hem svcutil programina hemde direk proje icine command prompt açabiliyoruz.
Bunla ilgili gerekli bilgi asagidaki sitede mevcuttur:

http://www.c-sharpcorner.com/UploadFile/rmcochran/CommandPromptInStudioToolsMenu01152008103357AM/CommandPromptInStudioToolsMenu.aspx

Arama Kriterleri:

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>