• WCF 事件处理


    最近工作中遇到这样一个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
        }
    }

  • 相关阅读:
    记一次对网站的SEO优化改造
    pc端页面添加响应式布局
    linux开启coredump
    vue中鼠标事件
    垂直居中的几种方法
    最准确的身份证号码正则验证
    将数组[NaN ,1,21,32,NaN,41,5]里面的NaN成员剔除(复用underscore.js的filter方法)
    项目中使用Mockjs模拟数据
    研究生学习与生活(2019)
    研究生学习与生活(九)
  • 原文地址:https://www.cnblogs.com/forrestsun/p/2022316.html
Copyright © 2020-2023  润新知