现在的位置: 首页 > 综合 > 正文

WCF 事件处理

2013年06月14日 ⁄ 综合 ⁄ 共 4793字 ⁄ 字号 评论关闭

最近工作中遇到这样一个WCF问题,宿主程序加载WCF服务后需要得到服务的反馈消息。

问题:宿主启动后与服务是分离状态,如何及时得到服务的反馈消息?如果是在winform中我们可以直接通过事件取得,这于WCF的实现有所不同。

处理方式:

参用WCF实现订阅/发布方式实现服务消息向订阅者发布

具体代码:

参考:WCF 事件 Events ,Oreilly.Programming.WCF.Services.3rd.Edition.Aug.2010.pdf

契约

using System;
using System.ServiceModel;
 
namespace ConsoleServer
{
    [ServiceContract(SessionMode = 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);  } 
}

 

服务

using System;
using System.Diagnostics;
using System.ServiceModel;
using System.Collections.Generic;
 
namespace ConsoleServer
{
    [ServiceBehavior(IncludeExceptionDetailInFaults = true, InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]  
    public class LogService:ILogService
    {
        Dictionary<string, OperationContext> listeners = new Dictionary<string, OperationContext>();
 
        public LogService() 
        {
            Trace.WriteLine("Create LogService Instance.");  
        }
 
        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 
    }
}

调用

using System;
using System.ServiceModel;
 
namespace ConsoleServer
{
    class Program
    {
        static void Main(string[] args)
        {
 
            try
            {
                using (ServiceHost host = new ServiceHost(typeof(LogService)))
                {
                    host.AddServiceEndpoint(typeof(ILogService), new NetNamedPipeBinding(),
                        "net.pipe://localhost/LogService");
 
                    host.Opened += (sender, e) =>
                    {
                        Console.WriteLine("service is start");
                        LogClient client = new LogClient();
                        ILogService service = DuplexChannelFactory<ILogService>.CreateChannel
                            (client, new NetNamedPipeBinding(), 
                            new EndpointAddress("net.pipe://localhost/LogService"));
 
                        service.RegisterListener();
                        service.Write("client start");
                        Console.ForegroundColor = ConsoleColor.White;
                        Console.WriteLine("press any key exits");
                        Console.ReadLine();
                        service.UnregisterListener();
                    };
                    host.Open();
                  
                }
            }
            catch (Exception ex)
            {
 
                Console.WriteLine(ex.Message);
            }
            Console.ReadLine();
        }
    }
 
    public class LogClient : IWriteLogCallback
    {
        #region IWriteLogCallback Members
 
        public void OnWriteLog(string logMsg)
        {
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine(logMsg);
        }
 
        #endregion
    }
}

抱歉!评论已关闭.