最近工作中遇到这样一个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 Memberspublic void OnWriteLog(string logMsg)
{Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(logMsg);
}
#endregion}
}
浙公网安备 33010602011771号