MSMQ Nedir?
MSMQ zaman bağımsız olarak birden fazla uygulama arasında offline veri alışverişini sağlayan Windows tabanlı kuyruk sistemidir. MSMQ ile birlikte uygulama veya ağ üzerinde bir sorun oluşsa dahi (çökme, hata fırlatma vb.) akış, gerçekleşen sorun giderildikten sonra veya çöken/çalışmayı durduran uygulama tekrar çalışmaya başladıktan sonra devam eder.
MSMQ ile iletilen mesajlar sistem üzerinde fiziksel bir alanda saklanmaktadır. Bu noktada yukarıda bahsetmiş olduğumuz senaryolar dahil, mesajları alması beklenen uygulama kapalı olsa dahi bu mesajlar saklanmaktadır.
Resim 1: Oluşturduğunuz Queue’ları Computer Management Ekranından Görmeniz Mümkün (compmgmt.msc)
Kuyruk Tipleri
MSMQ için iki adet kuyruk tipi mevcut;
Public Queues:
Bu tipte oluşturulmuş olan kuyruklara, yalnızca oluşturulduğu sunucu/bilgisayardaki uygulamalardan değil, aynı ağa bağlı tüm sunucu/bilgisayarlardan erişim sağlanabilmektedir. Bu sayede aynı ağda bulunan iki farklı sunucu ve bu sunucularda kurulu olan farklı uygulamalar arasında da MSMQ aracılığı ile mesaj iletimi sağlanabiliyor.
Private Queues:
Bu tipte oluşturulmuş olan kuyruklara ise yalnızca oluşturulduğu bilgisayar/uygulama üzerinden erişim sağlanabilir ve yalnızca aynı bilgisayar/sunucu üzerinde kurulu olan uygulamalar bu kuyruktan beslenebilir ve bu kuyruğu besleyebilir.
Programlanabilirlik
MSMQ alt yapısı C#, VB.NET ve .NET tabanlı diğer diller tarafından kullanılabilmektedir. System.Messaging namespace’i altından erişilebilir.
Kurulum
Eğer MSMQ sistemini bilgisayarınıza kurmak isterseniz, aşağıdaki adımları takip edebilirsiniz.
- Denetim Masası üzerinden “Programlar” seçimini yapın, ardından açılan ekranda “Programlar ve Özellikler” altında bulunan “Windows Özelliklerini Aç veya Kapat” seçimini yapın. Veya Windows + R tuş kombinasyonu ile “optionalfeatures” komutunu çalıştırabilirsiniz.
- Açılan pencerede “Microsoft Message Queue (MSMQ) Server” seçeneğini işaretleyin
Resim 2: “Windows Özelliklerini Aç veya Kapat” seçimi sonrası açılan pencereden “Microsof Message Queue (MSMQ) Server” özelliği işaretlenmeli.
Aynı kurulumu Windows Sunucu üzerinde yapmak için ise aşağıdaki adımları izlemelisiniz;
- Server Manager açıldıktan sonra Sağ üst tarafta bulunan Manage altından, “Add Roles and Features” seçilir.
- Açılan pencereden Features adımına gelindikten sonra listeden “Message Queuing” özelliği işaretlenir. Bu seçimin ardından “Install” butonu tıklanır ve özelliğin aktif edilme süreci bağlar. Bu işlemin ardından sunucunuzu yeniden başlatmanız gerekmez.
Resim 3: Features adımı altındaki listeden “Message Queuing” seçimi yapılır ve Install butonu tıklanarak kurulum süreci başlatılır.
C# Uygulamalarında MSMQ’yu Kullanmak
MSMQ’nun ne olduğundan ve nasıl kurulduğundan bahsettiğimize göre, örnek bir senaryo üzerinden bir C# uygulamasında MSMQ’nun sağladığı kuyruk alt yapısından nasıl faydalanabiliriz inceleyelim.
Senaryomuz; PeakUp’ta yeni işe başlayan personelin bilgisi sisteme girildiğinde, ilgili çalışana mail atmak olsun. Bu senaryoda ihtiyacımız olan iki uygulama var;
- Personel bilgilerinin girileceği uygulama
- Farklı uygulamalardan gelen mail gönderme taleplerini karşılayacak ve mailleri gönderecek uygulama.
İlk uygulamamızın ismi Peakup.Employee.Manager olsun. Projemizin yapısı aşağıdaki gibi;
PeakUp.Empoyee.Manager
-
Extensions
- MessageQueueExtensions.cs (MessageQueue sınıfı için yazacağımız extension metotlar)
-
Models
- EmployeeModel.cs (Personel sınıfı)
- Mail.cs (Mail Sınıfı)
- Program.cs
Önemli
MessageQueue sınıfını kullanabilmemiz için her iki projemize de System.Messaging referansını eklememiz gerekiyor.
Şimdi kodlara göz atalım:
Oluşturmak istediğimiz isimde bir Queue zaten varsa onu getirmek, yoksa tekrar oluşturmak gerekiyor. Bu işlemi daha hızlı bir şekilde gerçekleştirmek için bu Extension metodu kullanabilirsiniz.
public static class MessageQueueExtensions | |
{ | |
public static MessageQueue CreateIfNotExists(this MessageQueue messageQueue, string queueName) | |
{ | |
//Bu alanda ".\Private$" yolu, oluÅturmak/bulmak istediÄimiz queue'nin private olduÄunu belirtiyor. Ardından dosya yoluna queue ismi ile devam ediyoruz. | |
if (MessageQueue.Exists($@".\Private$\{queueName}")) | |
{ | |
//Queue mevcut, bu queue için bir C# objesi oluÅturup dönüyoruz. | |
return new MessageQueue($@".\Private$\{queueName}"); | |
} | |
else | |
{ | |
//Queue mevcut deÄil, "Create" metodu ile yeni bir queue oluÅturup, bu queue'nun C# objesini dönüyoruz. | |
return MessageQueue.Create($@".\Private$\{queueName}"); | |
} | |
} | |
} |
Employee ve Mail sınıflarımız;
public class EmployeeModel | |
{ | |
public EmployeeModel(string name, string mailAddress) | |
{ | |
this.Name = name; | |
this.MailAddress = mailAddress; | |
} | |
public string Name { get; set; } | |
public string MailAddress { get; set; } | |
} |
public class Mail | |
{ | |
public Mail(string to, string content) | |
{ | |
this.To = to; | |
this.Content = content; | |
} | |
public string To { get; set; } | |
public string Content { get; set; } | |
} |
Yeni personel oluşturma ve bu personeli mail için kuyruğa atma işlemlerini yaptığımız program dosyamız;
using Newtonsoft.Json; | |
using PeakUp.Employee.Manager.Extensions; | |
using PeakUp.Employee.Manager.Models; | |
using System; | |
using System.Messaging; | |
using System.Threading; | |
namespace PeakUp.Employee.Manager | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
//Kullanıcıdan Personel Bilgilerinin Alınması | |
Console.WriteLine("Personelin Adı"); | |
var employeeName = Console.ReadLine(); | |
Console.WriteLine("Personelin E-Posta Adresi"); | |
var employeeMailAdress = Console.ReadLine(); | |
//Alınan Bilgiler ile Employee objesinin oluÅturulması | |
var employee = new EmployeeModel(employeeName, employeeMailAdress); | |
//HoÅgeldin Maili için Personelin KuyruÄa Eklenmesi | |
AddEmployeeToQueue(employee); | |
//Personelin OluÅturulduÄuna Dair Mesaj | |
Console.WriteLine("Personel oluÅturuldu, teÅekkürler."); | |
//Mesajın Ekranda 1 saniye kalması için Thread'i uyutuyoruz | |
Thread.Sleep(1000); | |
} | |
static void AddEmployeeToQueue(EmployeeModel employee) | |
{ | |
// Email Queue zaten bilgisayarda/sunucuda mevcut ise getirilmesi, deÄilse oluÅturulup getirilmesi (Detaylar için Extensions altında bulunan CreateIfNotExists metodunun incelenmesi gerekiyor. | |
var emailQueue = new MessageQueue().CreateIfNotExists("mail"); | |
//string veri alıÅveriÅi yaptıÄımızdan dolayı emailQueue için string tipinde bir formatter tanımlıyoruz | |
Type formatterType = typeof(string); | |
emailQueue.Formatter = new XmlMessageFormatter(new Type[] { formatterType }); | |
//Mail objesinin oluÅturulması | |
var mail = new Mail(employee.MailAddress, $"Aramıza hoÅgeldin {employee.Name}"); | |
//Gönderilen mesajların daha kolay yazılıp, daha kolay okunabilmesi için JSON'a çevrilmesi (Opsiyonel) | |
var mailJson = JsonConvert.SerializeObject(mail); | |
//Mesajın queue'ya gönderilmesi | |
emailQueue.Send(mailJson); | |
} | |
} | |
} |
İkinci uygulamamızın ismi ise PeakUp.Email.Manager. Projemizin yapısı aşağıdaki gibi;
PeakUp.Email.Manager
-
Extensions
- MessageQueueExtensions.cs (MessageQueue sınıfı için yazacağımız extension metotlar)
-
Models
- Mail.cs (Mail Sınıfı)
- Program.cs
Bu projemizin kodları da aşağıdaki gibi;
Oluşturmak istediğimiz isimde bir Queue zaten varsa getirmek, yoksa tekrar oluşturmamız gerekiyor. Bu işlemi daha hızlı bir şekilde gerçekleştirmek için bu Extension metodu kullanabilirsiniz.
public static class MessageQueueExtensions | |
{ | |
public static MessageQueue CreateIfNotExists(this MessageQueue messageQueue, string queueName) | |
{ | |
//Bu alanda ".\Private$" yolu, oluÅturmak/bulmak istediÄimiz queue'nin private olduÄunu belirtiyor. Ardından dosya yoluna queue ismi ile devam ediyoruz. | |
if (MessageQueue.Exists($@".\Private$\{queueName}")) | |
{ | |
//Queue mevcut, bu queue için bir C# objesi oluÅturup dönüyoruz. | |
return new MessageQueue($@".\Private$\{queueName}"); | |
} | |
else | |
{ | |
//Queue mevcut deÄil, "Create" metodu ile yeni bir queue oluÅturup, bu queue'nun C# objesini dönüyoruz. | |
return MessageQueue.Create($@".\Private$\{queueName}"); | |
} | |
} | |
} |
Mail sınıfımız;
public class Mail | |
{ | |
public Mail(string to, string content) | |
{ | |
this.To = to; | |
this.Content = content; | |
} | |
public string To { get; set; } | |
public string Content { get; set; } | |
} |
Mail kuyruğunu dinleyen ve mail sınıfını konsola yazdıran program dosyamız;
using Newtonsoft.Json; | |
using PeakUp.Email.Manager.Extensions; | |
using PeakUp.Email.Manager.Models; | |
using System; | |
using System.Messaging; | |
namespace PeakUp.Email.Manager | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
// Email Queue zaten bilgisayarda mevcut ise getirilmesi, deÄilse ise oluÅturulup getirilmesi (Detaylar için Extensions altında bulunan CreateIfNotExists metodunun incelenmesi gerekiyor. | |
var emailQueue = new MessageQueue().CreateIfNotExists("mail"); | |
//string veri alıÅveriÅi yaptıÄımız için emailQueue için string type bir formatter tanımlıyoruz | |
Type formatterType = typeof(string); | |
emailQueue.Formatter = new XmlMessageFormatter(new Type[] { formatterType }); | |
//ReceiveCompleted Event'ini gelen mesajları okuyabilmek için takip etmemiz gerekiyor. | |
emailQueue.ReceiveCompleted += EmailQueue_ReceiveCompleted; | |
//Gelen mesajları almaya baÅlamak için BeginReceive() metodunu çaÄırmamız gerekiyor. | |
emailQueue.BeginReceive(); | |
Console.ReadKey(); | |
} | |
private static void EmailQueue_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e) | |
{ | |
//Sender objesi MessageQueue tipine dönüÅtürülür | |
var mailQueue = (MessageQueue)sender; | |
//Json formatında gönderdiÄimiz mesajı tekrar objeye çeviriyoruz. | |
var mailObject = JsonConvert.DeserializeObject<Mail>((string)e.Message.Body); | |
//Gelen mesajı konsola yazdırıyoruz | |
Console.WriteLine($"Gönderilecek adres: {mailObject.To}, Mesaj: {mailObject.Content}"); | |
//Mesaj almaya devam etmek için BeginReceive metodunu tekrar çaÄırıyoruz. | |
mailQueue.BeginReceive(); | |
} | |
} | |
} |
Bir C# projesinde MSMQ kullanan bu yazımızın sonuna gelmiş olduk. Bu konuyla ilgili daha fazla detaya ihtiyaç duyuyor veya örnekleri beraber incelemek istiyorsanız Live Coding Sessions‘larımızı takip etmeyi ihmal etmeyin!
Teşekkürler!