Makale Özeti

Bu yazımızda Microsoft Message Queuing Servisini (MSMQ) ve bu servisin C# ile nasıl kullanılabileceğini anlatmaya çalışacağım.

Makale

 

Bu yazımızda Microsoft Message Queuing Servisini (MSMQ) ve bu servisin C# ile nasıl kullanılabileceğini anlatmaya çalışacağım.

  1. MSMQ nedir?

MSMQ değişik zamanlarda birbirinden bağımsız olarak çalışan uygulamalar veya sistemler arasında veri transferi (mesajlaşma) yapılabilmesini sağlayan bir teknolojidir.

MSMQ , sistemler arasında sürekli bir bağlantı gerektirmemektedir. Bu da sistemlerin asenkron olarak yüksek performanslı ve veri kaybı olmaksızın  çalışmalarını sağlar.

İki çeşit queue bulunmaktadır.

    • Private Queues : Sadece Queue nun kurulu olduğu bilgisayarda yaratılabilen  ve Message Queue Information Service (MQIS) veritabanında saklanmayan queue lardır.

 

    • Public Queues : Her uygulamaya açık , network üzerinden erişilebilen herhangi bir server üzerinde kurulu queue lardır. Bu queue lar MQIS veritanında tutulurlar Bu tür bir queue bulunduran bilgisayarlar , istemcilerin erişebilmesi için ortak bir Active Directory e bağlı olmalıdırlar.

 

  1. MSMQ nasıl kurulur?

MSMQ opsiyonel bir servis olduğu için işletim sisteminin kurulumu sırasında  direkt olarak yüklenmez.Bu servisi kullanmak istiyorsanız ,ya ilk kurulum sırasında kurmalısınız, ya da daha sonra Control Panel/Add or Remove Programs /Add/Remove Windows Components adımını seçerek ekrana gelen listeden Message Queuing yanındaki kutuyu seçip kurma işlemini başlatabilirsiniz. (Sekil 1)

 

                                                                        Şekil 1

MSMQ servisini ve mesajları Computer Management/Services and Applications/ MessageQueuing altından kontrol edebilir, queue ların özellikleri ile ilgili değişklikleri buradan yapabilirsiniz. Eğer bilgisayarınızda böyle bir adım yoksa MSMQ servisi bilgisayarınıza kurulmamıştır.

 

 

  1. MSMQ nun C# ile kullanımı.

Bilgisyarınızdaki veya networkünüzde herhangi bir bilgisayar üzerindeki MSMQ servisine, Visual Studio .Net üzerinden erişebilir, herhangi bir .Net destekleyen programla dili ile de mesaj yazabilir ve okuyabilirsiniz. Örneğimiz C# ile yazılmış bir console uygulamasıdır.

Örneğimizi kişisel bir bilgisayarda yaptığımız  için Private bir queue ya erişim yapacağız.

Herhangi bir .Net uygulamasında MSMQ servislerini kullanabilmek için uygulamanıza System.Messaging.dll ini eklemeniz gerekmektedir. Çünkü kullanacağımız MessageQueue ve Message sınıfları(class) System.Messaging isim uzayının (namespace) içinde bulunmaktadırlar.

Aşağıda da gördüğünüz üzere uygulamamız 4 parçadan oluşmaktadır.

1.       YazGelistir isimli bir queue nin varlığını kotrol eden , yoksa yaratan kısım.

2.       Queue ya mesaj yazan kısım.

3.       Queue dan mesaj okuyan kısım.

4.       Queue yu silen kısım.

using System;

using System.Messaging;

 namespace MSMQ

{

      class MSMQ

      {

            [STAThread]

            static void Main(string[] args)

            {

                  CreateQueue();

                  WriteToQueue();

                  ReadFromQueue();

                  DeleteQueue();

}

     

            Şimdi her parçanın kodunu teker teker inceleyelim.

    • CreateQueue

            #region  CreateQueue

            private static void CreateQueue()

            {

                  if(!MessageQueue.Exists(@".\Private$\YazGelistir"))

                  {

                        MessageQueue.Create(@".\private$\YazGelistir");

                        Console.WriteLine("Queue yaratıldı.");

                  }

            }

            #endregion

Mesajlarımızı Private Queue lar altındaki YazGelistir isimli bir queue ya yazmak istiyoruz.

 

if(!MessageQueue.Exists(@".\Private$\YazGelistir")) ifadesi ile Queue nun varolup olmadığına bakıyoruz.Eğer tanımlı değilse

MessageQueue.Create(@".\private$\YazGelistir"); ifadesi ile bir Queue yaratıyoruz ve “Queue Yaratıldı” şeklinde bir mesaj veriyoruz.

 

Burada dikkat edilmesi gereken noktalardan biri queue nun hangi bilgisayar üzerinde yaratılcağını “.” ile belirtmiş olmamızdır.

Bu ifade, üzerinde çalıştığımız bilgisayarı ifade etmektedir.

Başka bir bilgisayardaki Message Queue ya erişim yapılacak ise “.” yerine o bilgisayarın IP Adresi veya Adı yazılmalıdır.

* FormatName ifadesi ile bir queue ya erişim

Herhangi bir MSMQ ya erişim için , erişilecek MSMQ nun yeri belirtilirken FormatName ifadesi ile erişim şekli, protokol , MSMQ adı gibi parametreler verilerek MSMQ ya erişim de mümkündür. Örneğin:

queue.Path =”FormatName:DIRECT=TCP:10.1.1.1\private$\YazGelistir”

queue.Path =”FormatName:Public = CBGEF98G-W2E4-XC0O-PKL4-KLM12O793NB4

İlk ifade TCP üzerinden 10.1.1.1 ip adresli bilgisayardaki private$\YazGelistir adli MSMQ ya erişim sağlar.

İkinci ifade ise CBGEF98G-W2E4-XC0O-PKL4-KLM12O793NB4 guid li Public Queue ya erişim sağlar.

    • WriteToQueue

            #region WriteToQueue

            private static void WriteToQueue()

            {

                  MessageQueue msqueue= new MessageQueue();

                  queue.Path=@".\private$\YazGelistir";

                  Message message= new Message();

                  message.Formatter=new BinaryMessageFormatter();

                  message.Label="Örnek Mesaj";

                  message.Body="Merhaba";

                  queue.Send(message);

                  queue.Close();

            }

#endregion

Bu metod ile, CreateQueue metodu yarattığımız queue ya bir mesaj yazacağız. Bunun için “queue” adında yeni bir mesaj queue nesnesi yaratıyoruz. Queue nesnesinin erişmesi gereken path i ise

queue.Path=@".\private$\YazGelistir"; ifadesi ile belitiyoruz.

 

Ardından “message” adında bir mesaj nesnesi yaratıyoruz. Böylelikle queue ya yazılacak mesaja ait özellikleri tanımlamayabiliyoruz.

 

message.Formatter=new BinaryMessageFormatter(); ifadesi ile yazılacak mesajın formatını belirliyoruz.

 

message.Label="Örnek Mesaj"; ifadesi ile yazılacak mesajın etiketini ;

message.Body="Merhaba"; ile ise yazılacak mesajın içeriğini belirtiyoruz.

 

Mesajımızı belirttiğimiz Queue ya yazmak için ise queue.Send(message) ifadesini kullanıyoruz. Daha sonra queue.Close() ile queue yu kapatıyoruz.

 

    • ReadFromQueue

            #region ReadFromQueue

            private static void ReadFromQueue()

            {

                  MessageQueue queue= new MessageQueue();

                  queue.Path=@".\private$\YazGelistir";

 

                  Message message=queue.Receive();

                  message.Formatter=new BinaryMessageFormatter();

                  Console.WriteLine("Message Label: {0}", message.Label);

                  Console.WriteLine("Message Body : {0}", message.Body);

                  queue.Close();

            }

            #endregion

 

Örnek  kodumuzu incelemeye başlamadan önce MSMQ nun ilk

giren ilk çıkar (First in First Out - FIFO)yöntemi ile çalıştığını belitmeliyim. Dolayısı ile MSMQ dan mesaj okumaya başladığımızda , ilk okuduğumuz mesaj MSMQ ya ilk yazılmış mesaj olacaktır.

 

Gelelim örnek kodumuza. Burada okuma işleminin başka bir uygulama tarafından yapılacağı düşünüldüğünden tekrar queue adında bir nesne yaratılıyor. Queue nesnesinin okuyacağı MSMQ ise queue.Path kısmında belirtiliyor.

Message message=queue.Receive(); ifadesinde Message tipinde bir message değişkeni yaratılıyor ,queue.Receive ile de MSMQ ya yazılmış ilk mesaj alınıp message değikenine atanıyor.

 

message.Formatter=new BinaryMessageFormatter(); ifadesi ile de alınan mesajın formatı belirtiliyor.

 

Sonraki iki satırda ise sırasıyla ,okunan mesajın etiketi message.Label ve mesajın içeriği message.Body özellikleri alınarak ekrana yazdırılıyor ve son satırda queue.Close() ile queue kapatılıyor.

 

Receive ve Peek Metodları

MSMQ dan mesaj okumada iki metod kullanılabilir. Bunlardan biri bizim kullandığımız Receive() metodu, diğeri ise Peek() metodudur. Bu metodlar arasındaki temel farklılık Receive metodu ile okuduğunuz mesajın MSMQ dan silinmesidir. Peek metodu ile okunan mesajlar ise MSMQ dan silinmezler. Dolayısı ile bir MSMQ da birden fazla sisteme ait mesajları aynı queue altında topladıysanız , kendi sisteminize uygun mesajı bulmak için öncelikle Peek metodu ile mesajı inceleyip sonra ele alabilirsiniz.

 

Purge Metodu

Herhangi bir queue dan tüm mesajları silmek de mümkün. Örneğimizden yola çıkarsak ,queue.Purge(); ifadesi ile YazGelistir queue undaki tüm mesajları silmiş oluruz.

 

Herhangi bir queue daki verileri silmek Computer Management arayüzünden de mümkün. İlgili queue nun üzerine gelip sağ tıkladıktan sonra All Tasks/Purge ile queue daki tüm mesajlar silinebilir.

 

    • DeleteQueue

#region DeleteQueue

            private static void DeleteQueue()

            {

                  if(MessageQueue.Exists(@".\Private$\YazGelistir"))

                  {

                        MessageQueue.Delete(@".\private$\YazGelistir");

                        Console.WriteLine("Queue Deleted");

                  }

 

            }

   #endregion

 

DeleteQueue metodunda, if(MessageQueue.Exists(@".\Private$\YazGelistir")) ifadesi ile YazGelistir isimli queue nun olup olmadığına bakıyoruz.

 

MessageQueue.Delete(@".\private$\YazGelistir"); ifasesi ile de YazGelistir queue sunu siliyoruz.

 

 

 

5.    MSMQ de  Asenkron Programlama

Yazımızın başında MSMQ nun , sistemler arası asenkron olarak olarak konuşma sağladığından bahsetmiştik. Bu ifadeyi MSMQ ya erişimin  asenkron olmasıyla karıştırmamak gerekir. Yukarıdaki örneğimizde MSMQ ya erişimizde senkron bir bağlatı kurduk. Yazdığımız uygulama MSMQ da işi bitene kadar bekledi.

 

MSMQ ile işlem yaparken bu işlemlerin asenkron olmasını da sağlayabiliriz.

 

MessageQueue sınıfının BeginReceive(), BeginPeek()

metodları bulunmaktadır. Bu metodları kullanarak MSMQ da asenkron programlama yapılabilmektedir.

 

 

 

 

6.    MSMQ da Transactional İşlemler

MSMQ da da herhangi bir veritabanında yapılabildiği gibi Transactional işlemler yapılabilmektedir. Herhangi bir message queue da transactional işlem yapabilmek için yaratılan queue nun transactional olarak tanımlanması gerekmektedir. CreateQueue metodumuza dönersek, MessageQueue.Create(@".\private$\YazGelistir"); ifadesi ile bir queue yaratmıştık. Bu queue yu transactional olarak yaratabilmek için Create Metodunun ikinci parametresi olan transactional parametresini true yapmamız gerekmektadir.

MessageQueue.Create(@".\private$\YazGelistir",true); ifadesi ile yaratacağımız YazGelistir adlı message queue yu transactional olarak yaratmış oluruz.

 

MSMQ da transactional işlemler yapabilmek için bir Queue Transaction  nesnesi yaratılması gerekiyor. Aşağıdaki örnekte msqt adında bir Queue Transaction  nesnesi yaratılıyor.Mesajı queue ya göndermeden önce ,msqt.Begin() ile transaction başlatılıyor.

 

queue.Send(message,msqt) ifadesi ile mesaj MSMQ ya transaction içinde gönderiliyor. İşlem başarılı olursa msmq.Commit() ile transaction tamamlanıyor ve mesaj MSMQ ya yazılıyor.

 

Eğer mesajı yazma esnasında bir hata oluşursa msqt.Abort() ifadesi ile işlem geri alınıyor.

 

      private static void SendTransactionally()

      {

            MessageQueue queue= new MessageQueue();

            queue.Path=@".\private$\YazGelistir";

           

MessageQueueTransaction msqt= new MessageQueueTransaction();

            Message message= new Message();

            message.Formatter=new BinaryMessageFormatter();

            message.Label="Örnek Mesaj2";

            message.Body="Merhaba2";

           

            msqt.Begin();

            try

            {

                  queue.Send(message,msqt);

                  msqt.Commit();

            }

            catch(MessageQueueException)

            {

                  Console.WriteLine("Transaction Aborting");

                  msqt.Abort();

            }

            queue.Close();

      }

 

 

7.       Sonuç

Yazımızda MSMQ ile ilgili bir takım genel bilgiler ve C# ile MSMQ nun nasıl kullanılabileceğine dair temel bilgiler vermeye çalıştım.  Tabiki MessageQueue ve Message sınıflarındaki methodlar  ve  özellikler bunlarla sınırlı değil.Bu konudaki sorularınızı cemkubilays@hotmail.com adresinden bana gönderebilirsiniz.Umarım herkese yararlı bir yazı olmuştur.