WCF實現(xiàn)事件通知相關應用技巧介紹
WCF中有一些方法的應用對于初學者來說還是比較容易應用。只要熟練的聯(lián)系這些方法操作,一般都能牢固的掌握。看了一些WCF的例子,實現(xiàn)事件通知使用的是多播委托的特性,有點復雜,操作起來也不是很直觀,看到一堆委托和事件我一般頭就暈了。#t#
下面介紹一種使用觀察者模式WCF實現(xiàn)事件通知的簡單方法。沒別的,就是簡單,簡單最美。
工程代碼如下:
WCF實現(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是需要寫入的日志信息。當客戶單沒有調用RegisterListener()訂閱事件的時候,是不會收到寫日志的事件通知的,相應的要獲得寫日志的事件通知,就需要調用RegisterListener()方法。如果要取消訂閱就調用UnregisterListener()方法。寫日志的功能和事件的訂閱功能是分開的。
WCF實現(xiàn)事件通知2.服務實現(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ā)布事件的時候,如果調用訂閱者的回調函數(shù)失敗,就把該訂閱者從listeners移除。代碼很簡單,就不多說了。
WCF實現(xiàn)事件通知3.客戶端訪問
定義回調的客戶端:
- class LogClient:IWrite
LogCallback- {
- #region IWriteLog
Callback 成員- 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. 這里使用的是單實例的服務,所以需要進行多進程訪問的保護,才能實際使用。