WCF使用MSMQ通信
使用消息队列(Message Queue)可以实现服务端与客户端的异步通信,客户端/服务端 可以在与对方通信断开的情况下将信息保存到MSMQ中
实现如下效果:在不开启服务端的情况下,客户端将信息传入消息队列,当服务器端打开后即可从该消息队列中读取数据,MSMQ支持事务操作
准备条件:需要安装消息队列(控制面板-添加Windows组建-消息队列)
Contract:
[ServiceContract]
public interface IPlusSerOp
{
[OperationContract(IsOneWay=true)]//只能使用OneWay,因为MSMQ通信使用的是异步通信,不能获得返回状态
void Plus(int x);
}
Host:
behavior
//和普通服务实现类一样
class ServerPlusOper:IPlusSerOp
{
#region IPlusSerOp 成员
public void Plus(int x)
{
Util.ServerOpeMap.add(x.ToString());
}
#endregion
}
宿主
//宿主需要打开MSMQ通道
static void startMSMQ()
{
string path = @".\WCFService";//此处path需对应address
if (!MessageQueue.Exists(path))
{
MessageQueue.Create(path, true);
}
using (ServiceHost host = new ServiceHost(typeof(ServerPlusOper)))
{
host.Opened += delegate
{
Console.WriteLine("MSMQService start");
};
host.Open();
Console.Read();
host.Close();
}
}
配置文件
<bindings>
<netMsmqBinding >
<binding name="localMSMQ">
<security>
<transport msmqAuthenticationMode="None" msmqProtectionLevel="None" />
<message clientCredentialType="None" />
</security>
</binding>
</netMsmqBinding>
</bindings>
<service name="Host.ServerPlusOper">
<!--MSMQ的address不能指定端口号-->
<endpoint address="net.msmq://localhost/WCFService" binding="netMsmqBinding"
bindingConfiguration="localMSMQ" contract="Contract.IPlusSerOp"></endpoint>
</service>
Util
//用于保存服务端数据
class ServerOpeMap
{
private static List<string> ParmsList = new List<string>();
private static ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
public static void add(string parm)
{
try
{
rwlock.EnterWriteLock();
ParmsList.Add(parm);
}
finally
{
rwlock.ExitWriteLock();
}
getAll();
}
public static void getAll()
{
try
{
rwlock.EnterReadLock();
foreach (var x in ParmsList)
{
Console.WriteLine("--ut--");
Console.WriteLine(x);
}
}
finally
{
rwlock.ExitReadLock();
}
}
}
客户端:
配置文件(和服务端相同配置)
<bindings>
<netMsmqBinding >
<binding name="localMSMQ">
<security>
<transport msmqAuthenticationMode="None" msmqProtectionLevel="None" />
<message clientCredentialType="None" />
</security>
</binding>
</netMsmqBinding>
</bindings>
<endpoint name="msmqBind" address="net.msmq://localhost/WCFService"
binding="netMsmqBinding" bindingConfiguration="localMSMQ"
contract="Contract.IPlusSerOp"></endpoint>
访问服务
static void MsmqSer()
{
ChannelFactory<IPlusSerOp> factory = new ChannelFactory<IPlusSerOp>("msmqBind");
IPlusSerOp service = factory.CreateChannel();
//MSMQ支持使用事务
using (TransactionScope tra = new TransactionScope())
{
service.Plus(1);
tra.Complete();
}
}