|
Web Servislerine Senkron ve Asenkron Erişim |
|
Gönderiliyor lütfen bekleyin... |
|
|
Web sevisleri ile
ilgili diğer yazılarda web servislerinin nasıl oluşturulduğunu, web servislerinin
arkasında yatan ayrıntıları ve bir web servisine çeşitli uygulama ortamlarından(Web,Mobile,Windows)
ne şekilde erişelebileciğini incelemiştik. Bu yazıda ise web servislerine erişim
tekniklerini inceleyeceğiz. Eğer web servisleri ile ilk defa ilgileniyorsanız
bu yazıyı okumadan önce diğer yazıları okumanızda fayda var.
Bildiğiniz gibi Web Servisleri dağıtık yapıda uygulama geliştirme mimarisinin
son yıllarda parlayan yeni yıldızıdır. Henüz ülkemizde web servisleri ile ilgili
olağanüstü çalışmalar yapılmamakla beraber halihazırda yapılan çalışmaların
verdiği memnuniyetin derecesi ilerleyen yıllarda web servisi kullanımının gittikçe
artacağının bir göstergesidir. Yazımızın ana konusu olan web servislerine erişim
metotlarına geçmeden önce web servislerinin altında yatan gerçekten biraz bahsetmek
istiyorum : Bir web servisi TCP/IP yada farklı protokol tabanlı bir ağda bulunan
herhangi bir bilgisayardaki uygulamayı temsil etmektedir. Bu uygulama yine aynı
ağ üzerindeki diğer bilgisayarlar tarafından erişilebilir bir durumdadır. Ağdaki
bilgisayarda bulunan herhangi bir web servisi uygulaması diğer bir bilgisayar
ile ancak belirli kurallar çerçevesinde haberleşebilir. Bu kuralların tamamı
W3C standartlar komitesi tarafından SOAP adı altında birleştirilmiştir. SOAP'ın
, XML tabanlı bir standart olması ve web servisi ile istemci uygulama arasındaki
haberleşmenin HTTP protokolü üzerinden gerçekleşmesi web servislerinin öneminin
artmasındaki en büyük etkendir. Zira, XML ve HTTP dünya çapında kabul gören
standartlardır.
.NET uygulama geliştirme ortamında web servislerine erişmek ve web servislerini
oluşturmak inanılmaz derecede kolaydır. Bu noktada web servislerinin oluşturulması
ve web servislerine erişim ile ilgili diğer makaleleri okumanızda fayda var.
Çünkü bu yazıda web servislerinin oluşturulması ve uygulamaya geçirilmesini
bildiğiniz varsayılacaktır.
Web servislerine erişimi iki ana başlık altında incelemek mümkündür. Bu iki
yöntem aşağıda detaylı bir şekilde anlatılacaktır.
1
- Web Servislerine HTTP Üzerinden Erişim
Bu başlık altında vurgulanması gereken konu şudur : Web servisleri ne .NET ne
de diğer herhangi bi platforma özgü bir teknoloji değildir. We Servisleri W3C
tarafından standartlaştırlmış bir uygulama geliştirme modelidir. O halde .NET
yada başka platformların dışından da web servislerine erişebilmek mümkün olmalıdır.
Web servislerine HTTP üzerinden erişildiğine göre hepimizin çok iyi bildiği
HTTP-Get ve HTTP-Post yöntemleriyle basit bir HTML sayfasından da web servislerine
erişebiliriz. Ancak bu yöntemde bazı kısıtlarımızın olacağı kesindir. Örneğin
bu yöntemle sadece temel veri tiplerinden olan int,string, array gibi tipleri
kullanabiliriz. .NET'teki DataSet gibi büyük bir veri yapısını web servisleri
üzerinden bu yöntemle iletmek daha büyük bir çalışma gerektirir. Halbuki .NET
gibi bir platformun çekirdeğinde bulunan serileştirme(serialization) ve eşleştirme(mapping)
teknikleri ile büyük veri yapılarınıda web servisleri ile taşımak mümkündür.
HTTP-Get yada HTTP-Post yöntemleri ile web servislerine erişiminin diğer bir
dezavantıjıda web servisinin istemciye göndereceği cevap bilgisinin karışık
olmasıdır. Web servisinden istemciye gelen bilgi XML formatında olduğu için
bu bilgiyi kullanmak için ayrıca bir XML ayrıştırıcıya(parser) ihtiyaç duyulacaktır.
Diğer bir erişim metoduna geçmeden önce bu yöntem ile ilgili bir örnek verelim.
www.csharpnedir.com sitesindeki DortIslem isimli bir servisi kullanacağımızı
düşünelim. Bu servis Topla, Cıkar, Carp ve Bol gibi 4 ayrı web metodu sunuyor
olsun. Bir HTML dosyasından bu web servisinin Topla metoduna aşağıdaki gibi
erişmemiz mümkündür. (Topla metodu int türden iki parametre almakta ve bu iki
parametrenin toplamı ile geri dönmektedir.)
Yukarıdaki Sayi1
ve Sayi2 input parametreleri "form action" kısmında belirtilen web
servisinin metoduna parametre olarak geçirilecektir. Bu web servisinden dönen
cevap eğer Sayi1= 2 ve Sayi2 = 3 ise ise aşağıdaki gibi olacaktır.
Web servisinden
gelen yukarıdaki XML formatındaki bilgiyi uygulama mantığımızın içinde kullanabilmek
için DOM yada SAX tabanlı herhangi bir XML ayrıştırıcı kullanılabilir.
2
- Web Servislerine SOAP Üzerinden Erişim
Bu yöntemde web servisine istekte bulunan uygulama bir windows yada web uygulaması
olabilir. Bu durumda web servisine yine HTTP isteği gönderilir. Ancak isteğin
gönderiliş şekli ve cevabın ele alınış biçimi farklıdır. Uygulamaların web servisine
erişmesi için, servisin ağda hangi bilgisayarda bulunduğunun bilinmesi gerekir.
Eğer web servisinin bulunduğu bilgisayar biliniyorsa .NET ile birlikte gelen
WSDL aracı kullanılarak web servisinin sunduğu arayüz belirlenir. Daha sonra
bu arayüz üzerinden gerçek web servisine erişim sağlanır. İsterseniz WSDL aracının
ürettiği dağıtıcı sınıf(proxy class) üzerinde biraz duralım. Proxy sınıflar,
gerçek web servisi ile uygulamamız arasında bir bağlantı sağlar. Uygulamamız
proxy sınıfını kullanarak normal bir nesne yaratır. Bu nesne üzerinden proxy
sınıftaki metotlara erişilir. Bu erişimin ne şekilde olacağı ve erişelen web
servisinin adresi proxy sınıf içerisinde tanımlanmıştır. Proxy sınıf web servisindeki
public metotların bildirimlerini içermektedir. Örnek bir proxy sınıfının içeriği
aşağıda gösterlmiştir.
Önce bir web servisi ve bu web serviste bir web metodu oluşturmalıyız. Aşağıda
parametre olarak gelen string değişkenini şifreli olarak geri döndüren bir web
metodu görüyorsunuz.
[WebMethod]
public string Encode(string
anahtar)
{
char[] Kaynak
= anahtar.ToCharArray();
string Sifreli
= null;
for(int
i=0; i < Kaynak.Length ;i++)
Sifreli +=
((char)((int)Kaynak[i]
+ 3)).ToString();
return
Sifreli.ToString();
}
|
wsdl aracını aşağıdaki
gibi kullanarak proxy sınıfını oluşturabilirsiniz.
wsdl /l:cs /n:İsimAlani /out:Servis.cs http://localhost/WS/Service1.asmx
/n: parametresi ile proxy sınıfnın hangi isimalanında oluşturulacağını /out:
parametresi ise proxy sınıfnın dosya sisteminde nerde oluşturulacağını belirtir.
/l:cs parametresi de oluşturulacak proxy sınıfının hangi dilde olacağını belirtir.
Yukarıdaki komutu çalıştırdıktan sonra oluşan proxy sınıfının içeriği aşağıdaki
gibidr.
Not : Eğer Visual Studio.NET aracını kullanıyorsanız "Add Web Reference"
menüsünden ilgili web servisinin adresini seçtiğinizde proxy sınıfı otomatik
olarak oluşturulur.
namespace
IsimAlani {
using System.Diagnostics;
using System.Xml.Serialization;
using System;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Web.Services;
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="Service1Soap",
Namespace="http://tempuri.org/")]
public class Service1 : System.Web.Services.Protocols.SoapHttpClientProtocol
{
public Service1()
{
this.Url
= "http://localhost/WS/encode/service1.asmx";
}
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/Encode",
RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/",
Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public string Encode(string
anahtar)
{
object[] results = this.Invoke("Encode",
new object[]
{
anahtar});
return
((string)(results[0]));
}
public System.IAsyncResult
BeginEncode(string anahtar, System.AsyncCallback
callback, object asyncState)
{
return
this.BeginInvoke("Encode", new
object[] {
anahtar},
callback, asyncState);
}
public string EndEncode(System.IAsyncResult
asyncResult)
{
object[]
results = this.EndInvoke(asyncResult);
return
((string)(results[0]));
}
}
}
|
Yukarıdaki proxy
sınıfında bulunan metotlar web servisinin senkron ve asenkron şekillerde çağrılmasına
olanak sağlamaktadır. Web servisindeki metot ile aynı parametrik yapıya sahip
olan Encode() metodu web servisinin senkron biçimde, BeginEncode()
ve EndEncode() metotları ise web servisine asenkron bir biçimde erişilmesine
olanak tanır. Ayrıca proxy sınıf içerisinde bir adet de yapıcı metot bulunmaktadır.
Bu yapıcı metot içerisinde web servisinin gerçek adresi belirtilmektedir. Görüldüğü
üzere proxy sınıfları uygulama ile web servisi arasındaki bağlantıyı sağlayan
yapıdır. Bu bağlantının ne şekilde sağlanacağına dair bilgiler ise çeşitli nitelik(attribute)
bilgileri ile bildirilmiştir.
Eğer WSDL gibi bir araç olmasaydı yukarıdaki kodların tamamını uygulamamız içinde
kulanıp web servislerine herhangi bir proxy sınıfı olmadan da erişebilirdik.
Ancak her bir web servisi için yukarıdaki kodları tekrarlamamak programcıya
hem zaman kazandırmakta hemde arkan plandaki karışık seneryoların gizlenmesini
sağlamaktadır.
Uygulamalar web servisleri ile genel olarak iki biçimde iletişim kurabailirler.
Bunlar senkron ve asenkron iletişim yöntemleridir. Aşağıda bu iki yöntemde detaylı
bir şekilde anlatılmıştır.
2.1
Senkron Erişim
Daha öncede dediğim gibi proxy sınıfındaki Encode() metodu ile web servisine
senkronize bir biçimde bağlanılır. Yani web servisine bağlantı isteği gönderildikten
sonra web servisinden cevap gelene kadar programın akışı durdurulur. Web servisinden
cevap geldiği anda program kaldığı yerden akışına devam eder. Örneğin;
static
void Main()
{
IsimAlani.Service1 Srvc = new
IsimAlani.Service1();
string
sifreli = Srvc.Encode("csharpnedir");
Console.WriteLine(sifreli);
}
|
şeklindeki bir
kod bloğunda akış metodun ikinci satırına geldiğinde programın devam edebilmesi
için web servisinden cevabın başarılı ile gelmiş olması gerekir.
2.2
Asenkron Erişim
Eğer web servisinden gelecek yanıt programın akışının devam edebilmesinde etkin
rol oynuyorsa senkron iletişim tekniği kullanılmalıdır. Aksi halde asenkron
iletişim yöntemi daha uygundur. Örneğin bir web servisi windows uygulamanızın
"treeview" kontrolünü veritabanındaki verilerle doldururken siz arka
planda uygulamanızla ilgili diğer işlemleri yapabilirsiniz. Böylece asenkron
iletişimle birden fazla bağımsız işlemin paralel olarak işletilmesini sağlayabilirsiniz.
Bu yöntem ile bir anlamda çoklu kanal uygulamalarını uzaktaki servisler üzerinde
uygulamış oluyoruz.
Web metotlarının asenkron bir biçimde çağrılması için proxy sınıfındaki EndEncode()
ve BeginEncode() metotları kullanılır. Dikkat ettiyseniz bu metotların
parametrik yapısı orjinal web metodunun parametrik yapısından farklıdır. Zaten
asenkon bir iletişim sağlayabilemk için farklı olan bu parametrik yapıyı kullanacağız.
BeginEncode() metodu servisin işletilmesini sağlar, ve anında bir geri dönüş
değeri üretir. Ancak bu geri dönüş değeri web metodundan gelen cevap değildir.
Bu metot asenkron iletişim için gerekli olan IAsyncResult arayüzü referansı
döndürür. Bu arayüzü içinde AsyncWaitHandle isim bir özellik bulunmaktadır.
Bu özellik yardımıyla web metodunun bir metot için, herhangi bir metot için
yada bütün metotlar için bekletileceği belirtilir.
Asenkron iletişim de genel olarak iki biçimde yapılabilir. Birincisi senkronizasyon
nesneleri kullanılarak paralel işlemlerin BeginEncode() metodunun çağrıldığı
metodun içinde yapıldığı durumdur. İkinci yöntemde ise paralel işlemler farklı
metotlar içinde yapılır. Bu yöntem genellikle "Callback" olarak anılır.
Şimdi sırayla bu iki yöntemin nasıl uygulamay geçirildiğini inceleyelim.
2.2.1 Senkronizasyon Nesneleri ile Asenkron İletişim
Bu yöntemde izlenilmesi gereken senaryo şöyledir : Web servisine bağlantı isteği
BeginEncode() metodu ile sağlanır ve metodun geri dönüş değeri IAsyncResult
arayüzü türünden bir referansa aktarılır. Ardından bu referans yardımıyla
AsyncWaitHandle özelliği ilgili metot ile değiştirilir. Örneğin web metodunun
sadece bir metodu beklemesi için AsyncWaitHandle özelliğinin WaitOne()
metodu kullanılabilir. Aynı şekilde WaitAny() ve WaitAll() metotları
da kullanılabilir. BeginEncode() metodu çağrıldıktan sonra EndEncode()
metodu ile web servisinden web metodunun orjinal geri dönüş değeri alınır.
Bu bilgiyi elde edebilmek için EndEncode() metoduna BeginEncode()
metodunun geri dönüş değeri olan IAsyncResult türünden referansı
geçirmeliyiz. Aklınıza şu soru gelmiş olabilir: Bu yöntemin senkron iletişim
yönteminden ne farkı var? Bu sorunun oluşması gayet normal, çünkü henüz daha
asenkron iletişimin faydasını incelemedik. İsterseniz bunuda kod üzerinde anlatalım.
Aşağıdaki örnekte bir üst parağfta anlatılan senaryo koda aktarılmıştır.
static
void Main()
{
IsimAlani.Service1 Srvc = new
IsimAlani.Service1();
System.IAsyncResult syncResult = Srvc.BeginEncode("csharpnedir",null,null);
syncResult.AsyncWaitHandle.WaitOne();
/*
Bu bölgeye istenildiği kadar kod yazılabilir.
*/
string
sifreli = Srvc.EndEncode(syncResult);
Console.WriteLine(sifreli);
}
|
Yukarıdaki kod
bloğundan da görüldüğü üzere web servisine bağlantı isteği gerçekleştikten sonra
herhangi bir kod bloğu çalıştırılabilir. Yeşil bölgedeki kodların icrası sırasında
web metodu da bir yandan uygulamaya cevabını iletmektedir. EndEncode()
metodu çağrıldığı anda web metodunun orjinal geri dönüş değeri elde edilir.
Eğer EndEncode() metodu çağrıldığı anda web servisinden henüz cevap gelmediyse
programın akışı cevap gelene kadar bir sonraki satıra geçmez.
Not : BeginEncode() metodunun ilk paramtresi orjinal web metodunun
paramtresini temsil etmektedir. Diğer iki parametre ise "CallBack"
yönteminde kullanılır. Eğer "CallaBack" yöntemi uygulanmıyorsa bu
iki parametre null olarak geçirilebilir. "CalBack" yöntemi aşağıda
açıklanmıştır.
2.2.1
"CallBack" Yöntemi ile Asenkron İletişim
Bu yöntemde web servisine asenkron bir biçimde erişim tamamlandığı anda bir
metodun çalıştırılması sağlanır. Web metodunun işlemini gerçekleştirdiği anda
diğer bir metodun çağrılması için temsilcilerden(delegates) faydalanılır. "CallBack"
yöntemi ile asenkron iletişimde senaryo şu şekilde olmaktadır : Öncelikle bir
web servisi nesnesi oluşturulur. Web metodu başarı ile icra edildikten sonra
çağrılacak metodu temsil etmek için AsyncCallback temsilcisi türünden
bir nesne tanımlanır. Bu temsilcinin temsil ettiği metotların IAsyncResult
türünden tek bir parametresi olmalıdır. Aynı zamanda geri dönüş değeri de void
olmalıdır. Bu işlemden sonra web servisi nesnesi üzerinden BeginEncode()
metodu çağrılır. Metodun gerçek parametreleri girildikten sonra son iki özel
parametre de girilmelidir. Sondan bir önceki parametre AsyncCallback
türünden bir temsilci nesnesidir. Sonuncu parametre ise object türünden web
servisi referansıdır. Bu referans, temsilcinin temsil ettiği metot içinden kullanılarak
EndEncode() metoduna erişilir ve web metodundan gelen cevap alınır.
Yukarıdaki senaryoyu kod üzerinde görmekte elbette fayda var :
using
System;
namespace
ConsoleApplication1
{
class mainClass
{
static
void Main()
{
IsimAlani.Service1
Srvc = new IsimAlani.Service1();
AsyncCallback
callback= new AsyncCallback(mainClass.CallbackMetodu);
I
AsyncResult sifreli = Srvc.BeginEncode("csharpnedir",callback,Srvc);
Console.WriteLine("paralel
kodlar buraya yazilmali");
//CallBack
metodunun çagrilabilmesi için bu noktadan sonra
//web
servisine erisilip cevabin alinmasi sirasinda geçecek süre
//kadar
zaman alan islem yapilmalidir.
}
public
static void CallbackMetodu(IAsyncResult asyncResult)
{
IsimAlani.Service1
srvc = (IsimAlani.Service1)asyncResult.AsyncState;
string
sifreli = srvc.EndEncode(asyncResult);
Console.WriteLine(sifreli);
}
}
}
|
Yukarıdaki programı
bu haliyle çalıştırdığınızda muhtemelen "csharpnedir" yazınısın şifreli
halini ekranda göremeyeceksiniz. Çünkü web metodu icra edilemeden önce program
sonlandırılmıştır. Bu yüzden yorum satırları içinde yazılanları dikkate almanız
gerekmektedir. Yukarıdaki programın beklenen çıktıyı vermesi için Main() metodunun
son satırına
Console.ReadLine();
satırını ekleyebilirsiniz. Böylece web metodunun icra edilmesi için yeteri kadar
zaman kazanmış olacaksınız. Hemen şunuda eklemek gerekir ki web metodunun icarası
bittiği anda o anda çalışan metot ne olursa olsun programın akışı CallabackMetodu()
metoduna geçecektir.
Not : CallbackMetodu() içerisinde srvc referansının ne şekilde elde edildiğine
özellikle dikkat edin.
2.3
Sonuç
Her ne kadar birçok programcı içgüdüsel olarak web servislerine senkron iletişim
tekniği ile erişiyor olsada asenkron iletişim yöntemi uygulamanızın ihtiyaçları
ve iş mantığınızın(business logic) türü göz önünde bulundurulup kullanıldığı
zaman uygulamanızın performansı artacaktır.
Makale:
Web Servislerine Senkron ve Asenkron Erişim XML ve Web Servisleri Sefer Algan
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|