In recent work, the host program needs to receive service feedback after loading the WCF Service.
Q: After the host is started, it is separated from the service. How can I get service feedback in a timely manner? If it is in winform, we can directly obtain it through the event, which is different from the implementation of WCF.
Processing Method:
Use WCF to subscribe to/publish a service message to a subscriber
Code:
Reference: WCF Event Events, oreilly.programming.wcf.services.3rd.edition.aug.2010.pdf
Contract
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); }
}
Service
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 Member
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
}
}
Call
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
}
}