Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subscribe to events within a WCF service

I have a need to do some real-time reporting on the functionality of a WCF service. The service is self-hosted in a windows app, and my requirement is to report "live" to the host app when certain methods are called by the client.

My initial thought on the task was to publish a "NotifyNow" event in the service code, and subscribe to the event in my calling app, but this doesn't seem to be possible. Within my service code (implementation, not the interface) I have tried adding the following

public delegate void MessageEventHandler(string message);
public event MessageEventHandler outputMessage;

void SendMessage(string message)
{
    if (null != outputMessage)
    {
        outputMessage(message);
    }
}

and call the SendMessage method whenever I need to notify the host app of some action. (This is based on what I remember of this kind of inter-form communication in a winforms app, and my memory may have let me down here...)

When I try to hook up the event handler in my host, though, I can't seem to figure out how to attach to the events... My hosting code is (in a nutshell)

service = new ServiceHost(typeof(MyService));
service.outputMessage += new MyService.MessageEventHandler(frm2_outputMessage);
  // the above line does not work!
service.Open();

(wrapped in a try/catch).

Can anyone help, either by telling me how to get this approach to work or by pointing me at a better way.

TIA

like image 800
ZombieSheep Avatar asked Oct 08 '09 11:10

ZombieSheep


3 Answers

The service variable is an instance of ServiceHost not your service implementation. Try something like:

MyService myService = new MyService();
myService.outputMessage += new MyService.MessageEventHandler(frm2_outputMessage);
host = new ServiceHost(myService);
like image 193
Maurice Avatar answered Oct 19 '22 00:10

Maurice


I did some more research this morning, and turned up a much simpler solution than has been outlined already. The main source of information was this page, but it is summarised here.

1) in the service class, add the following (or similar) code..

public static event EventHandler<CustomEventArgs> CustomEvent;

public void SendData(int value) 
{       
    if (CustomEvent != null)
        CustomEvent(null, new CustomEventArgs());
}

The important bit is to make the event static, otherwise you'll have no chance of catching it.

2) Define a CustomEventArgs class, for example...

public class CustomEventArgs : EventArgs
{
    public string Message;
    public string CallingMethod;                        
}

3) Add calling code in each method of the service in which you have an interest...

public string MyServiceMethod()
{
    SendData(6);
}

4) Instantiate the ServiceHost as normal, and hook into the event.

ServiceHost host = new ServiceHost(typeof(Service1));
Service1.CustomEvent += new EventHandler<CustomEventArgs>(Service1_CustomEvent);
host.Open();

5) Handle the event messages that bubble up to the host from there.

like image 34
ZombieSheep Avatar answered Oct 19 '22 00:10

ZombieSheep


You seem to be instantiating a default ServiceHost class:

service = new ServiceHost(typeof(MyService));
              ***********
service.outputMessage += new MyService.MessageEventHandler(frm2_outputMessage);
  // the above line does not work!

and I highly doubt that would have a "outputMessage" property for an event handler.

Shouldn't you be instantiating your own custom service host, something like this:

class MyCustomServiceHost : ServiceHost
{
  ...... your custom stuff here ......
}

service = new MyCustomServiceHost(typeof(MyService));
              *******************
service.outputMessage += new MyService.MessageEventHandler(frm2_outputMessage);

??

Marc

like image 29
marc_s Avatar answered Oct 19 '22 00:10

marc_s