Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visual feedback for a self-hosting WCF service

I have a windows service that is hosting a WCF service on a server. I am using InstanceContextMode.PerSession attribute. The services function well per my requirements.

I would now like to implement a visual feedback for the WCF service, like a logger, preferably in a list box in a windows form. I would like all calls from all clients and the subsequent actions to be recorded in this form. I read that having a UI for a service is not a good idea. Can someone point me in a direction to achieve this in a thread safe way.

like image 531
swiftgp Avatar asked Dec 18 '25 03:12

swiftgp


2 Answers

I think that the simpliest answer is this one. Basically what you can do is to define a custom trace listener for your wcf service. You can modify the example in order to get the results you want.

Custom Trace implementation looks like this:

namespace WcfTrace.Trace
{
    public class WebTraceListener : TraceListener
    {
        public override void Write(string message)
        {
            //write you custom code here
            Debug.WriteLine(message);
        }

        public override void WriteLine(string message)
        {
            //write your custom code here
            Debug.WriteLine(message);
        }
    }
}

Configuration on your service host has to include this:

<system.diagnostics>
    <sources>
      <source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
        <listeners>
          <add name="xml" />
        </listeners>
      </source>
      <source name="System.ServiceModel.MessageLogging">
        <listeners>
          <add name="xml" />
        </listeners>
      </source>
    </sources>
    <sharedListeners>
      <add name="xml" type="WcfTrace.Trace.WebTraceListener,WcfTrace.Trace" />
    </sharedListeners>
  </system.diagnostics>

  <system.serviceModel>
    <diagnostics>
      <messageLogging
      logEntireMessage="true"
      logMalformedMessages="false"
      logMessagesAtServiceLevel="true"
      logMessagesAtTransportLevel="false"
      maxMessagesToLog="300000"
      maxSizeOfMessageToLog="200000"/>
    </diagnostics>
  </system.serviceModel>

Personally I like this idea, the tracer class independet from the client (the app with the listbox you mention) can consume information from this custom trace implementation, as well as anything else can do in the future.

like image 68
danielQ Avatar answered Dec 21 '25 01:12

danielQ


The Service does not have a UI but the host may.

This is just a console host but it displays text from the service.

Those Console.WriteLine in the Service display in the host.

namespace MagicEightBallServiceHost
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("**** Console Based WCF Host *****");

            using (ServiceHost serviceHost = new ServiceHost(typeof(MagicEightBallService)))
            {
                serviceHost.Open();
                Console.WriteLine("The service is running");
                Console.ReadLine();
            }

[ServiceBehavior (InstanceContextMode=InstanceContextMode.PerSession)]
    public class MagicEightBallService : IEightBall, IDisposable
    {
        private DateTime serviceStartTime;
        public void Dispose()
        {

            Console.WriteLine("Eightball dispose ... " + OperationContext.Current.SessionId.ToString() + " " + serviceStartTime.ToLongTimeString());          
        }
        public MagicEightBallService()
        {
            serviceStartTime = DateTime.Now;
            Console.WriteLine("Eightball awaits your question " + OperationContext.Current.SessionId.ToString() + " " + serviceStartTime.ToLongTimeString());
        }
        public string ObtainAnswerToQuestion(string userQuestion)
        {
            Console.WriteLine("Eightball ObtainsAnser " + OperationContext.Current.SessionId.ToString() + " " + serviceStartTime.ToLongTimeString());
            return "maybe " + OperationContext.Current.SessionId.ToString() + " " + serviceStartTime.ToLongTimeString() ;
        }
like image 33
paparazzo Avatar answered Dec 21 '25 01:12

paparazzo