Coding WCF Publisher/Susbcriber Model

30 07 2007

Before going through this post, please have a look here and here to get familiar with Publisher/Subscriber Model.

This post will give you code snippets on how I implemented the above model. I built 3 components,

1) PubSubService

2) PubSubClient

3) Publisher

PubSubService

This is our main Service which allows the Client to Subscribe, Unsubscribe and the Publisher to Publish messages to the subscribed clients. Our Service also has a CallBackContract which is going to be our source at the Client for notifications sent out by the Service

Below is our ServiceContract Interface.

 

[ServiceContract(Namespace = "http://ListPublishSubscribe.Service",
SessionMode = SessionMode.Required, CallbackContract = typeof
(IPubSubContract))]
public interface IPubSubService
{
        [OperationContract(IsOneWay = false, IsInitiating=true)]
        void Subscribe();
        [OperationContract(IsOneWay = false, IsInitiating=true)]
        void Unsubscribe();
        [OperationContract(IsOneWay = false)]
        void PublishNameChange(string Name);
}

It is pretty clear what we have. Our ServiceContract SessionType is set to be SessionMode.Required, so, you have to connect the client and a session is required and it has three OperationContracts namely,

1) Subscribe

2) UnSubscribe

3) PublishNameChange

The IsOneWay tells that its not a one way contract and its two way contract meaning that this contract can be called by the Client as well return some values back to the Client. IsInitiating tells that this contract can initiate a session in the Server/Service.

We have specified the interface IPubSubContract as our CallbackContract. This means that this would be a medium of data exchange between the Service and Client and using this Callbacks we can actually make Sercive notify the Clients regarding specific events.

Below is our IPubSubContract interface

 

public interface IPubSubContract
{
        [OperationContract(IsOneWay = true)]
        void NameChange(string Name);
}

We just have one OperationContract called NameChange. We would be go into this soon.

As now we have our Interfaces defined, its time to implement our ServiceContract and below is the Class which implements the above IPubSubService interface.

 

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
 public class PubSubService : IPubSubService
 {
    public delegate void NameChangeEventHandler(object sender, ServiceEventArgs e);
    public static event NameChangeEventHandler NameChangeEvent;

    IPubSubContract ServiceCallback = null;
    NameChangeEventHandler NameHandler = null;

    public void Subscribe()
    {
        ServiceCallback = OperationContext.Current.GetCallbackChannel<IPubSubContract>();
        NameHandler = new NameChangeEventHandler(PublishNameChangeHandler);
        NameChangeEvent += NameHandler;
    }

    public void Unsubscribe()
    {
        NameChangeEvent -= NameHandler;
    }

    public void PublishNameChange(string Name)
    {
        ServiceEventArgs se = new ServiceEventArgs();
        se.Name = Name;
        NameChangeEvent(this, se);
    }

    public void PublishNameChangeHandler(object sender,ServiceEventArgs se)
    {
        ServiceCallback.NameChange(se.Name);

    }
}

We have implemented our already defined three OperationContracts and also we have defined some delegates and events.

What are those ?

The logic is simple. Whenever a Client subscribes, we create an eventhandler and add to our event which is NameChangeEvent. So what happens here, if “n” number of Clients join, we have “n” number of eventhandlers referring to those Clients.

How is this accomplished ?

Simple. Create a Delegate, associate an event to it and in the DelegateHandler, we call the ServiceCallback’s NameChange contract when we want to Publish and since its a CallbackContract and implemented in the Client, this function would be invoked in the Client and thus we have Published our message to the Client

So, If you look in the PublishNameChangeHandler, you could see that we invoke the ServiceCallback.NameChange which makes it clear

I have hosted the PubSubService in IIS to make things simpler

Now, lets move on to our PubSubClient

PubSubClient

Here, we are going to add our WCF Service, implement the IPubSubContract interface to get the Callback from the Service, Susbcribe to the Service and be ready to recieve messages when our Publisher publishes them

Add your PubSubService through the Add Service Reference. If you are not familiar, have a look at my post regarding adding WCF Sercvice to your Application.

Our PubSubClient is a normal Windows Form Application having just a Label in the Form and this Label will be updated when a message is Published by the Publisher.

I have used PubSubService as the Reference for my Service.Once you add the PubSubService , we get our PubSubService.map and PubSubService.cs through which now you can implement the IPubSubContract.

 

[CallbackBehaviorAttribute(UseSynchronizationContext = false)]
public class ServiceCallback : IPubSubServiceCallback
{
      public void NameChange(string Name)
      {
             Client.MyEventCallbackEvent(Name);
      }
}

Our implementation is straight forward. We implement the NameChange contract here at our Client and now you should be able to bring out what I meant earlier. This way, when you call from the Service using the Callback, the funtion in the Client would be called.

What I have done in my NameChange function above ?

I have done Marshaling. Marshaling is used when you want to access variables in another environment or thread. And since our Windows Forms is running as a separate thread, and to use safe threading, I have used Marshaling here.

Implementing Marshaling is simple. We create a Delegate and associate an Event to it and make the event Static. We raise the event from the Service Callback and update the Label control in our Form.

Below is our client class and you can see all the Delegates, Events and also our ServiceCallback implementation done here.

 


public partial class Client : Form
{
     public delegate void MyEventCallbackHandler(string Name);
     public static event MyEventCallbackHandler MyEventCallbackEvent;

     delegate void SafeThreadCheck(string Name);

     [CallbackBehaviorAttribute(UseSynchronizationContext = false)]
     public class ServiceCallback : IPubSubServiceCallback
     {
         public void NameChange(string Name)
         {
             Client.MyEventCallbackEvent(Name);
         }
     }

     public Client()
     {
          InitializeComponent();            

          InstanceContext context = new InstanceContext(new ServiceCallback());
          PubSubServiceClient client = new PubSubServiceClient(context);

          MyEventCallbackHandler callbackHandler = new MyEventCallbackHandler(UpdateForm);
          MyEventCallbackEvent += callbackHandler;

          client.Subscribe();
     }

     public void UpdateForm(string Name)
     {
          if (lblDisplay.InvokeRequired)
          {
              SafeThreadCheck sc = new SafeThreadCheck(UpdateForm);
              this.BeginInvoke(sc, new object[] { Name });
          }
          else
          {
              lblDisplay.Text += Name;
          }
     }

 }

The only thing to keep in mind is the Marshaling. Here I use the BeginInvoke method so that it doesnt wait for that delegate handler to complete and the UI thread continues to do its work. If you use Invoke method, the UI thread waits till its operation is completed. It actually depends on the need to whether to use BeginInvoke or Invoke. You can also use Invoke here in the place of BeginInvoke.

Publisher

Publisher is the most simplest of all. We add our PubSubService, create the Service object and just invoke the PublishNameChange contract and thus that would invoke the ServiceCallback’s NameChange contract to the subscribed Clients and thus exchanging the data with the Clients.

Below is the Publisher code,

 

public partial class Publisher : Form
{
     InstanceContext context = null;
     PubSubServiceClient client = null;

     public class ServiceCallback : IPubSubServiceCallback
     {
         public void NameChange(string Name)
         {
              MessageBox.Show(Name);
         }
     }

     public Publisher()
     {
         InitializeComponent();
     }

     private void btnPublish_Click(object sender, EventArgs e)
     {
         context = new InstanceContext(new ServiceCallback());
         client = new PubSubServiceClient(context);
         client.PublishNameChange(txtMessage.Text);
         client.Close();
     }
}

So with this, the WCF Publisher/Subscriber Model gets over and I hope this helped you to understand how to do it with the help of WCF.

You can download the source from here 

Creative Commons License Creative Commons License

Advertisements

Actions

Information

4 responses

7 12 2007
Paul

Great article but missing some key pieces. I’d like to see all the code to see exactly how you implemented the full solution.

8 06 2012
Thunder

What are ServiceEventArgs ?

28 06 2013
affiliate help

Thanks in support of sharing such a pleasant idea, article is nice, thats why i have read it entirely

1 07 2013
homepage

Indeed could be your # 1 choice for job search. In some instances, you
simply must purchase once a year membership to sign up within the bidding for jobs.

This site claims it can be the #1 source for hourly employment, perhaps they
state this as this is suited more for part time jobs, new hires away from senior high school, not as much for career or maybe more paying salaried positions, like management or experienced workers.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: