8.WCF消息队列
配置消息队列:
1 控制面板\所有控制面板项\程序和功能->打开或关闭 Windows 功能。
安装 MSMQ
http://www.cnblogs.com/rhythmK/
2. 传统消息队列开发<单机模式>。
using System.Messaging;
2.1 接收端:
static void ReadMessage()
{
string queueName = @".\Private$\SampleQueue";
MessageQueue mq = new MessageQueue(queueName);
mq.Formatter = new XmlMessageFormatter(new[] { "System.String" });
Message msg = mq.Receive();
Console.WriteLine(msg.Label);
Console.WriteLine(msg.Body.ToString());
}
2.2 发送端:
static void SendMessage()
{
Message msg = new Message("这是我的一个消息");
string queueName = @".\Private$\SampleQueue";
MessageQueue mq = null;
if (!MessageQueue.Exists(queueName))
mq = MessageQueue.Create(queueName);
else
mq = new MessageQueue(queueName);
mq.Formatter = new XmlMessageFormatter(new[] { "System.String" });
mq.Send(msg, "测试消息");
Console.WriteLine("消息发送成功");
}
3. WCF 消息队列:
契约:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.ServiceModel; namespace LearnMSSQ.Service { [ServiceContract] [DeliveryRequirements(QueuedDeliveryRequirements = QueuedDeliveryRequirementsMode.Required)] public interface IOrder { /// <summary> /// 添加订单 Rhythmk.cnblogs.com /// </summary> /* 消息队列可以离线 ,则只能设置成单向访问。 */ [OperationContract(IsOneWay=true)] void AddOrder(string msg); } }
服务方法实现:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; namespace LearnMSSQ.Service { public class Order:IOrder { public void AddOrder(string msg) { string result = string.Format("传入的MSG={0}", msg); WriteTxt(result); } private static void WriteTxt(string txt) { string path = "D:\\MSSQ\\LearnMSSQ\\" + "\\log\\" + DateTime.Now.ToString("yyyyMMdd") + ".log"; System.IO.StreamWriter sw = new System.IO.StreamWriter(path, true); sw.Write(DateTime.Now.ToString()+"\r\n"+txt); sw.WriteLine(); sw.Close(); } } }
3.2 宿主:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;
using System.ServiceModel.Dispatcher;
using System.Messaging;
namespace LearnMSSQ.Host
{
class Program
{
static void Main(string[] args)
{
// 获取消息队列
string queueName = System.Configuration.ConfigurationManager.AppSettings["queueName"];
if (!MessageQueue.Exists(queueName))
{
MessageQueue.Create(queueName,true);
}
using (ServiceHost host = new ServiceHost(typeof(LearnMSSQ.Service.Order)))
{
host.Open();
Console.WriteLine("WCF - 消息队列已经启动!");
Console.ReadKey();
}
}
}
}
config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<!-- 私有队列-->
<add key="queueName" value=".\private$\order"/>
</appSettings>
<system.serviceModel>
<services>
<!--name - 提供服务的类名-->
<!--behaviorConfiguration - 指定相关的行为配置-->
<service name="LearnMSSQ.Service.Order" behaviorConfiguration="MessageBehavior">
<!--address - 服务地址-->
<!--binding - 通信方式-->
<!--contract - 服务契约-->
<!--bindingConfiguration - 指定相关的绑定配置-->
<endpoint address="" binding="netMsmqBinding" contract="LearnMSSQ.Service.IOrder" bindingConfiguration="MSMQBindingConfiguration" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8083/LearnMSSQ/Service"/>
<add baseAddress="net.msmq://localhost/private/order"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MessageBehavior">
<!--httpGetEnabled - 指示是否发布服务元数据以便使用 HTTP/GET 请求进行检索,如果发布 WSDL,则为 true,否则为 false,默认值为 false-->
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netMsmqBinding>
<binding name="MSMQBindingConfiguration" exactlyOnce="false">
<security>
<!--msmqAuthenticationMode - 指示 MSMQ 传输必须采用什么方式对消息进行身份验证,默认值 WindowsDomain -->
<!--MsmqAuthenticationMode.None - 不使用任何安全性-->
<!--MsmqAuthenticationMode.WindowsDomain - 通过 Kerberos 进行身份验证,客户端和服务器必须连接到受信任域-->
<!--MsmqAuthenticationMode.Certificate - 客户端通过 X.509 证书进行身份验证,客户端证书必须显示在服务器的证书存储区中-->
<!--msmqProtectionLevel - 保护级别,设置与 MsmqAuthenticationMode 相关联的 ProtectionLevel,默认值 Sign -->
<!--ProtectionLevel.None - 只做身份验证-->
<!--ProtectionLevel.Sign - 对数据做签名,以确保所传输数据的完整性-->
<!--ProtectionLevel.EncryptAndSign - 对数据做加密和签名,以确保所传输数据的保密性和完整性-->
<transport msmqAuthenticationMode="None" msmqProtectionLevel="None" />
<!--clientCredentialType - 客户端用以进行身份验证的凭据的类型,默认值 UserName -->
<!--BasicHttpMessageCredentialType.UserName - 使用用户名凭据对客户端进行身份验证-->
<!--BasicHttpMessageCredentialType.Certificate - 使用证书对客户端进行身份验证-->
<message clientCredentialType="UserName" />
</security>
</binding>
</netMsmqBinding>
</bindings>
</system.serviceModel>
</configuration>
3.3 客户端:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.ServiceModel; using LearnMSSQ.Service; using System.IO; namespace LearnMSSQ.Client { class Program { static void Main(string[] args) { Console.WriteLine("客户端启动"); Console.WriteLine("订单记录:" + AppDomain.CurrentDomain.BaseDirectory); wCFSend(); Console.ReadKey(); } private static void wCFSend() { NetMsmqBinding binding = new NetMsmqBinding(NetMsmqSecurityMode.None); binding.ExactlyOnce = false; binding.Durable = true; ChannelFactory<LearnMSSQ.Service.IOrder> channel = new ChannelFactory<LearnMSSQ.Service.IOrder>( binding, new EndpointAddress("net.msmq://localhost/private/order")); LearnMSSQ.Service.IOrder client = channel.CreateChannel(); for (var i = 0; i < 100; i++) { client.AddOrder(string.Format("订单ID:{0}", i)); Console.WriteLine("发送了一个订单mSg:{0}", i); } } } }