WCF事件通知具體實現(xiàn)方法詳解
WCF開發(fā)工具是由微軟公司推出的一款功能強大的開發(fā)插件,它在實際應(yīng)用中可以為我們提供許多有用的幫助。在這里我們將會為大家詳細介紹一下WCF事件通知的相關(guān)實現(xiàn)方法,以方便大家掌握這方面的應(yīng)用技巧。#t#
看了一些WCF的例子,實現(xiàn)WCF事件通知使用的是多播委托的特性,有點復(fù)雜,操作起來也不是很直觀,看到一堆委托和事件我一般頭就暈了。下面介紹一種使用觀察者模式實現(xiàn)事件通知的簡單方法。沒別的,就是簡單,簡單最美。
工程代碼如下:
1.定義接口
- [ServiceContract(SessionModeSessionMode = SessionMode.Required,
 
CallbackContract = typeof(IWriteLogCallback))]- public interface ILogService
 - {
 - [OperationContract(IsInitiating = true, IsTerminating = false)]
 - void Write(string logMsg);
 - [OperationContract(IsInitiating = true, IsTerminating = false)]
 - void RegisterListener();
 - [OperationContract(IsInitiating = false, IsTerminating = false)]
 - void UnregisterListener();
 - }
 - [ServiceContract]
 - public interface IWriteLogCallback
 - {
 - [OperationContract(IsOneWay = true)]
 - void OnWriteLog(string logMsg);
 - }
 
為了簡單舉了一個寫日志的例子, Write(string logMsg)就是寫入日志的方法,參數(shù)logMsg是需要寫入的日志信息。當客戶單沒有調(diào)用RegisterListener()訂閱事件的時候,是不會收到寫日志的WCF事件通知的,相應(yīng)的要獲得寫日志的事件通知,就需要調(diào)用RegisterListener()方法。如果要取消訂閱就調(diào)用UnregisterListener()方法。寫日志的功能和事件的訂閱功能是分開的。
2.服務(wù)實現(xiàn)
- [ServiceBehavior(
 - IncludeExceptionDetailInFaults = true,
 - InstanceContextModeInstanceContextMode = InstanceContextMode.Single,
 - ConcurrencyModeConcurrencyMode = ConcurrencyMode.Multiple)]
 - class LogService:ILogService
 - {
 - public LogService()
 - {
 - Trace.WriteLine("Create LogService Instance.");
 - }
 - Dictionary<string, OperationContext> listeners = new Dictionary
 
<string, OperationContext>();- private void BroadCast(string logMsg)
 - {
 - List<string> errorClints = new List<string>();
 - foreach (KeyValuePair<string, OperationContext> listener in listeners)
 - {
 - try
 - {
 - listener.Value.GetCallbackChannel<IWriteLogCallback>().OnWriteLog(logMsg);
 - }
 - catch (System.Exception e)
 - {
 - errorClints.Add(listener.Key);
 - Trace.WriteLine("BROAD EVENT ERROR:" + e.Message);
 - }
 - }
 - foreach (string id in errorClints)
 - {
 - listeners.Remove(id);
 - }
 - }
 - #region ILogService 成員
 - public void Write(string logMsg)
 - {
 - Trace.WriteLine("Write LOG:"+logMsg);
 - BroadCast(logMsg);
 - }
 - public void RegisterListener()
 - {
 - listeners.Add(OperationContext.Current.SessionId, OperationContext.Current);
 - Trace.WriteLine("SessionID:" + OperationContext.Current.SessionId);
 - Trace.WriteLine("Register listener. Client Count:" +
 
listeners.Count.ToString());- }
 - public void UnregisterListener()
 - {
 - listeners.Remove(OperationContext.Current.SessionId);
 - Trace.WriteLine("SessionID:" + OperationContext.Current.SessionId);
 - Trace.WriteLine("Unregister listener. Client Count:" +
 
listeners.Count.ToString());- }
 - #endregion
 - } Dictionary<string, OperationContext> listeners
 
包含了所有的事件訂閱者。發(fā)布WCF事件通知的時候,如果調(diào)用訂閱者的回調(diào)函數(shù)失敗,就把該訂閱者從listeners移除。代碼很簡單,就不多說了。
3.客戶端訪問
定義回調(diào)的客戶端:
- class LogClient:IWriteLogCallback
 - {
 - #region IWriteLogCallback 成員
 - public void OnWriteLog(string logMsg)
 - {
 - Trace.WriteLine("RECV LOG EVENT:" + logMsg);
 - }
 - #endregion
 - }
 
然后在程序中使用它:
- class Program
 - {
 - static void Main(string[] args)
 - {
 - Trace.Listeners.Add(new ConsoleTraceListener());
 - LogClient client = new LogClient();
 - ILogService service = DuplexChannelFactory<ILogService>
 
.CreateChannel(client,- new WSDualHttpBinding(), new EndpointAddress
 
("http://localhost:8888/log"));- //訂閱消息
 - service.RegisterListener();
 - service.Write("Client start");
 - Console.WriteLine("Press enter key to exit.");
 - Console.ReadLine();
 - service.UnregisterListener();
 - }
 
WCF事件通知實現(xiàn)時需要注意的問題:
A. 因為客戶也要監(jiān)聽端口,所以確保防火墻沒有對它進行阻止。
B. 這里使用的是單實例的服務(wù),所以需要進行多進程訪問的保護,才能實際使用。















 
 
 
 
 
 
 