1.何時需要使用Message Queuing (MSMQ):
2.使用C#撰寫MSMQ範例注意事項
3.實務應用注意事項
[應用情境]
MSMQ讓發送訊息端與接收端可以不是同時運作,如同Email的傳送與接收一樣
甚至允許傳送與接收端的網路是可以暫時中斷的
適用於以下類型的交易
1.重要的金融交易 如電子商務(保證成功)
2.外出的業務代表使用的銷售系統(離線交易)
3.工作流程(work flow): MQ讓你可以建立一個流程可以更新各個系統, 此方法可讓各系統鬆散偶合(Loose Coupling) 互相不被影響
讓你可以更安心的升級各系統
[實作]
1.開始動手寫程式之前: 安裝MSMQ:程式集/安裝Windows功能/Microsft Message Queue(MSMQ) 伺服器
2.git上的本專案範例:https://github.com/michaelfangtw/MyMSMQ
傳送端:MyMSMQSender
接收端:MyMSMQReceiver
參考引用: Microsoft.Messaging
參考引用: MyEntity.Customer (傳送接收此物件)
傳送端:MyMSMQSender Sample Code
MSMQ 傳送路徑: .\Private$\MyQueue
public static void SendMessage()
{
MessageQueue myQueue;
string path = "";
//local private
//path = ".\\private$\\MyQueue"; //本機
//path = @"FormatName:Direct=OS:fij-nb\private$\MyQueue"; //遠端主機名稱
path = @"FormatName:Direct=TCP:192.168.0.103\private$\MyQueue";//遠端主機IP
if (path.StartsWith(@".\"))// path=@".\Private$\MyQueue"
{
if (MessageQueue.Exists(path))
{
myQueue = new MessageQueue(path);
}
else
{
myQueue = MessageQueue.Create(path);
}
}
else
{
myQueue = new MessageQueue(path);
}
List<Customer> customerList = new List<Customer>();
customerList.Add(new Customer { CustomerID = "1", CustomerName = "Mike", Birthday = DateTime.Parse("1973/07/27"), Email = "yingchih.fang@gmail.com", CreateTime = DateTime.Now });
customerList.Add(new Customer { CustomerID = "2", CustomerName = "Dan", Birthday = DateTime.Parse("1973/08/19"), Email = "danise0819@gmai.com", CreateTime = DateTime.Now });
Message MyMessage = new Message();
//set formatter for Message
MyMessage.Formatter = new BinaryMessageFormatter();
MyMessage.Body = customerList;
MyMessage.Label = "customerList," + DateTime.Now.ToString("yyyyMMddHHmmss");
MyMessage.Priority = MessagePriority.High;
myQueue.Send(MyMessage);
Console.WriteLine("path:{0}", path);
}
接收端:MyMSMQReceiver SampleCode
public static int ReceiveMessage()
{
MessageQueue myMessageQueue;
string path = "";
//path = ".\\private$\\MyQueue"; //本機
//path = @"FormatName:Direct=OS:fij-nb\private$\MyQueue"; //遠端主機名稱
path = @"FormatName:Direct=TCP:192.168.0.103\private$\MyQueue";//遠端主機IP
myMessageQueue = new MessageQueue(path);
myMessageQueue.Formatter = new BinaryMessageFormatter();
Message[] messages = myMessageQueue.GetAllMessages();
int messageCount = 0;
Console.WriteLine("Receive MessageQueue from {0}", path);
Console.WriteLine("messages size:{0}", messages.Length);
foreach (Message message in messages)
{
messageCount++;
Message MyMessage = myMessageQueue.Receive();
List<Customer> customerList = (List<Customer>)MyMessage.Body;
Console.WriteLine("Message #{0}", messageCount);
Console.WriteLine("customerList.count:{0}", customerList.Count);
int count = 0;
foreach (Customer customer in customerList)
{
Console.WriteLine("Customer[{0}],CustomerID:{1},CustomerName:{2},CreateDate:{3} \r\n", count, customer.CustomerID, customer.CustomerName, customer.CreateTime.ToString("yyyy/MM/dd HH:mm:ss.fff"));
count++;
}
Console.WriteLine("");
}
return messageCount;
}
[後記]
注意事項:
1.參考引用: 若要傳送物件(e.g MyEntity.Customer) , 該物件需Sender/Receiver都要引用
2.path 的遠端主機格式注意,e.g path="FormatName:Direct=TCP:192.168.0.103\private$\MyQueue";
3.發送時Formatter 要設定為BinaryMessageFormatter , e.g: MyMessage.Formatter = new BinaryMessageFormatter();
4.接收物件後 要轉型: List<Customer> customerList = (List<Customer>)MyMessage.Body;
5.接收所有訊息: Message[] messages = myMessageQueue.GetAllMessages();
[參考]
1.Message Queuing (MSMQ)
https://msdn.microsoft.com/en-us/library/ms711472(VS.85).aspx
2.MSMQ remote queue path format
http://www.infosysblogs.com/microsoft/2007/05/msmq_receiving_messages_from_r.html