使用消息队列(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(); } }
配置文件
Util
//用于保存服务端数据 class ServerOpeMap { private static ListParmsList = new List (); 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(); } } }
客户端:
配置文件(和服务端相同配置)
访问服务
static void MsmqSer() { ChannelFactoryfactory = new ChannelFactory ("msmqBind"); IPlusSerOp service = factory.CreateChannel(); //MSMQ支持使用事务 using (TransactionScope tra = new TransactionScope()) { service.Plus(1); tra.Complete(); } }