跟着Artech学习WCF(4) MSMQ 绑定
曾几何时 再看大家讨论各种构架时,经常出现在各个服务器间传递数据,经常出现MSMQ,
那是看到这个心理就郁闷,怎么整天折腾ASP.NET 就没遇见过这个东西
原来这个家伙藏在WCF里面
嘿嘿这次被我发现了
首先 第一次装IIS的话 默认是没有安装msmq 所以需要自己安装的
看Artech 的介绍 这个东西在不能时刻保持和服务器连接的情况下 使用非常有用
对于以WEB为构架为核心的 系统我虽然不知道这个东西有什么用
但我觉得在移动应用中这个东西应该比较有用
移动客户端和服务器端总是若离若弃
但不知道 移动客户端支不支持 这个东西 例如 WINCE ,wp7 支不支持
项目结构图如下
代码如下
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.Transactions; using cfContract; namespace cfClient { class Program { static void Main(string[] args) { ChannelFactory<IOrderProcessor> channelFactory = new ChannelFactory<IOrderProcessor>("defaultEndpoint"); IOrderProcessor channel = channelFactory.CreateChannel(); Order order = new Order(Guid.NewGuid(), DateTime.Today, Guid.NewGuid(), "A Company"); order.OrderItems.Add(new OrderItem(Guid.NewGuid(), "PC", 5000, 20)); order.OrderItems.Add(new OrderItem(Guid.NewGuid(), "Printer", 7000, 2)); Console.WriteLine("Submit order to server"); using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required)) { channel.Submit(order); scope.Complete(); } Console.Read(); } } }
==================
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.Serialization; using System.ServiceModel; namespace cfContract { [ServiceContract] [ServiceKnownType(typeof(Order))] public interface IOrderProcessor { [OperationContract(IsOneWay = true)] void Submit(Order order); } }
=================================
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.Runtime.Serialization; namespace cfContract { [DataContract] [KnownType(typeof(OrderItem))] public class Order { #region Private Fields private Guid _orderNo; private DateTime _orderDate; private Guid _supplierID; private string _supplierName; private IList<OrderItem> _orderItems; #endregion #region Constructors public Order() { this._orderItems = new List<OrderItem>(); } public Order(Guid orderNo, DateTime orderDate, Guid supplierID, string supplierName) { this._orderNo = orderNo; this._orderDate = orderDate; this._supplierID = supplierID; this._supplierName = supplierName; this._orderItems = new List<OrderItem>(); } #endregion #region Public Properties [DataMember] public Guid OrderNo { get { return _orderNo; } set { _orderNo = value; } } [DataMember] public DateTime OrderDate { get { return _orderDate; } set { _orderDate = value; } } [DataMember] public Guid SupplierID { get { return _supplierID; } set { _supplierID = value; } } [DataMember] public string SupplierName { get { return _supplierName; } set { _supplierName = value; } } [DataMember] public IList<OrderItem> OrderItems { get { return _orderItems; } set { _orderItems = value; } } #endregion #region Public Methods public override string ToString() { string description = string.Format("General Informaion:\n\tOrder No.\t: {0}\n\tOrder Date\t: {1}\n\tSupplier No.\t: {2}\n\tSupplier Name\t: {3}", this._orderNo, this._orderDate.ToString("yyyy/MM/dd"), this._supplierID, this._supplierName); StringBuilder productList = new StringBuilder(); productList.AppendLine("\nProducts:"); int index = 0; foreach (OrderItem item in this._orderItems) { productList.AppendLine(string.Format("\n{4}. \tNo.\t\t: {0}\n\tName\t\t: {1}\n\tPrice\t\t: {2}\n\tQuantity\t: {3}", item.ProductID, item.ProductName, item.UnitPrice, item.Quantity, ++index)); } return description + productList.ToString(); } #endregion } }
==================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text;
using System.Runtime.Serialization;
namespace cfContract
{
public class OrderItem
{
#region Private Fields
private Guid _productID;
private string _productName;
private decimal _unitPrice;
private int _quantity;
#endregion
#region Constructors
public OrderItem()
{ }
public OrderItem(Guid productID, string productName, decimal unitPrice, int quantity)
{
this._productID = productID;
this._productName = productName;
this._unitPrice = unitPrice;
this._quantity = quantity;
}
#endregion
[DataMember]
public Guid ProductID
{
get { return _productID; }
set { _productID = value; }
}
[DataMember]
public string ProductName
{
get { return _productName; }
set { _productName = value; }
}
[DataMember]
public decimal UnitPrice
{
get { return _unitPrice; }
set { _unitPrice = value; }
}
[DataMember]
public int Quantity
{
get { return _quantity; }
set { _quantity = value; }
}
}
}
===========================================
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.Messaging; using cfService; namespace cfHosting { class Program { static void Main(string[] args) { string path = @".\private$\orders"; //此计算机上尚未安装消息队列 if (!MessageQueue.Exists(path)) { MessageQueue.Create(path, true); } using (ServiceHost host = new ServiceHost(typeof(OrderProcessorService))) { host.Opened += delegate { Console.WriteLine("Service has begun to listen\n\n"); }; host.Open(); Console.Read(); } } } }
==========================================
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using cfContract; namespace cfService { public class OrderProcessorService:IOrderProcessor { [OperationBehavior(TransactionScopeRequired=true,TransactionAutoComplete=true)] void IOrderProcessor.Submit(Order order) { Orders.Add(order); Console.WriteLine("Receive an order."); Console.WriteLine(order.ToString()); } } }
===========================================================
using System; using System.Collections.Generic; using System.Linq; using System.Text; using cfContract; namespace cfService { public static class Orders { private static IDictionary<Guid, Order> _orderList = new Dictionary<Guid, Order>(); public static void Add(Order order) { _orderList.Add(order.OrderNo, order); } public static Order GetOrder(Guid orderNo) { return _orderList[orderNo]; } } }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
服务器端配置
<system.serviceModel>
<bindings>
<netMsmqBinding>
<binding name="msmqBinding">
<security>
<transport msmqAuthenticationMode="None" msmqProtectionLevel="None" />
<message clientCredentialType="None" />
</security>
</binding>
</netMsmqBinding>
</bindings>
<services>
<service name="cfService.OrderProcessorService">
<endpoint address="" binding="netMsmqBinding"
bindingConfiguration="msmqBinding" contract="cfContract.IOrderProcessor" />
<host>
<baseAddresses>
<add baseAddress="net.msmq://localhost/private/orders"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
客户端配置
<system.serviceModel>
<bindings>
<netMsmqBinding>
<binding name="msmqBinding">
<security>
<transport msmqAuthenticationMode="None" msmqProtectionLevel="None" />
<message clientCredentialType="None" />
</security>
</binding>
</netMsmqBinding>
</bindings>
<client>
<endpoint address="net.msmq://localhost/private/orders" binding="netMsmqBinding"
bindingConfiguration="msmqBinding" contract="cfContract.IOrderProcessor"
name="defaultEndpoint" />
</client>
</system.serviceModel>