Push Data to the Client using WCF CallBack Service

Posted by: Mahesh Sabnis , on 6/15/2011, in Category Windows Communication Foundation (WCF)
Views: 75624
Abstract: In WCF, callback is used to implement PUSH mechanism, so that delayed or long running operation results can be automatically pushed back to the client application. WCF actively supports callback to its client, over the instance context established. In this article, we will explore the same.

Many a times, the requirement demands that the WCF Service pushes data to the application that is consuming it, over the session established between client application and the WCF service. This mechanism can be termed as Callback. WCF actively supports callback to its client, over the instance context established. To understand this scenario, think of it like the WCF service becomes the client and the client becomes the service.

BasicHttpBinding and WSHttpBinding do not support callback. To support callback over HTTP transport, WCF provides WSDualHttpBinding. The WSDualHttpBinding sets up two channel - one for calls from client to service and other from service to client. Whenever you create a Service, it can have only one callback contract. When a proxy is created for the Service with CallBack, the base class of the proxy is the DuplexClientBase<T>. This is used to create channels for the duplex service and this channel is the associated with the callback object.

 

Enough of theory, let’s create a WCF service, Host and Client callback.

Step 1: Open VS2010 and create a Blank solution, name it as ‘WCF_Callback_Contract’. In this solution, add a new WCF Service application and name it as ‘WCF_CallBack_Service’. Rename IService1.cs to Iservice.cs and Service1.svc to Service.svc.

Step 2: Open IService.cs and add the following ServiceContract, Callback contract interface and a DataContract, as shown below:

wcf callback service

There are some important points to be noted here:

  • The method in the interface participating in Call-Back must be OneWay, so that there is no immediate response generated from the method. E.g. GetData() method in IService
  • The interface acting as Callback must also define OneWay method. E.g. IServiceCallback.

In the above code, since IServiceCallback interface is set as a CallbackContract of the IService service contract, it will automatically serialize through the proxy, to the client application. The client application can then subscribe to this interface, to receive callback from the WCF service.

Step 3: Open Service.svc.cs and implement the IService in the service class as shown below:

wcf-iservice-instantcontext

Step 4: Open Web.Config file and write the following configuration as shown below. Here we are using WSHttpBinding for Callback over Http transport.

wcf servicemodel WsHTTPBinding

Step 5: Publish and Host the service on IIS.

Step 6: In the solution created in Step 1, add a new WinForm project and name it as ‘Windows_Client_WCF_CallBack’. Add the WCF service reference in it. If you observe the proxy class, the base class for the proxy will be ‘DuplexClientBase<T>’. Along with this, you will also find the IServiceCallback, the callback contract in the proxy.

Step 7: Now this is the most important step. We need to implement the IServiceCallback contract in the client application so that the Callback from the WCF service can be received in the client. Here the client application acts as service and service acts as a client. In the client application, add a new class file and name it as ‘CallBackClass.cs’. Write the following code in it:

wcf iservice callback

The above code implements IServiceCallback interface and implements its SendResult() method. This method displays count of the department in the department array object.

Step 8: Design Form1.cs as shown below using  aButton and DataGridView:

WCF Callback Service App

Step 9: Open Form1.cs (the code behind) and declare the following object at Form1 class level:

MyRef.ServiceClient Proxy;

RequestCallBack callback;

Step 10: Write the following code in the Form Loaded event:

wcf request callback

The above code creates an instance of the RequestCallBack class created above in Step 7. Using this object, the context information of the service instance is acquired using InstanceContext class, then this context is passed to the Proxy object so that the WCF service can automatically send the request to the client application.

Step 11: Write the following code in the click event of the Get Data button. This is a very simple piece of code for making call to the WCF service:

WCF GetData Callback

Step 12: Run the application and click on the Get Data button. The result will be as shown below:

WCF Client to Service

The dialog-box shows that the value is posted from client to the WCF service. After a second, the result shown below will be displayed indicating the Service has made a callback to the client:

WCF Callback Service to Client

The ‘Response Received 3’ in the callback specifies the number of Department objects in Department array. Click OK on both the dialog-box and the Department data will be displayed in the DataGridView as below:

WCF CallBack Demo

Conclusion: In WCF, callback is used to implement the PUSH mechanism, so that delayed or long running operation results can be automatically pushed back to the client application.

The entire source code of this article can be downloaded over here

Give me a +1 if you think it was a good article. Thanks!
Recommended Articles
Mahesh is having 10 years of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) since 2005 and has conducted various Corporate Training programs for .NET Technologies (all versions). Follow him on twitter @maheshdotnet


Page copy protected against web site content infringement by Copyscape


User Feedback
Comment posted by Fabian Fernandez on Thursday, July 7, 2011 1:05 PM
Hi Mahesh.

We followed your tutorial but couldn't manage to get it working.

We also downloaded your source code and neither worked.

Did you uploaded the correct source code or are we doing something wrong?
Does your source code require a modification from our side to get it working?

Regards,
Fabian Fernandez
Comment posted by Varun on Tuesday, January 17, 2012 12:01 PM
Excellent job!

The code works for me and explains the concept well, thank you.
Comment posted by FoodBar on Wednesday, January 25, 2012 9:37 AM
@Fabian Fernandez
I had to make the following changes to the code to make this work:
public void SendResult(Department[] arrDept)
        {
            Departments = arrDept;
            MessageBox.Show("Response  Received " + Departments.Count().ToString());
            setData(); //added
        }

private Form1 _form = null;

        public RequestCallBack(Form1 form)
        {
            _form = form;
        }

        private void setData()
        {
            _form.setData();
        }
///form1
private void Form1_Load(object sender, EventArgs e)
        {
            callback = new RequestCallBack(this); //add "this"
            //Get the InstanceContext with the help of the CallBack contract class
            InstanceContext context = new InstanceContext(callback);
            Proxy = new ServiceReference1.ServiceClient(context);
        }
//add this function
        public void setData()
        {
            dgvDept.DataSource = callback.Departments;
        }
Comment posted by Seshu on Friday, April 27, 2012 3:44 AM
Mahesh, thanks for the article. Can you also let me know if the callback is possible with jQuery? thanks
Comment posted by somnath dey on Thursday, August 9, 2012 6:32 AM
Hi frnd,
  
   If you change service reference then it working fine.
  
Comment posted by somnath dey on Thursday, August 9, 2012 6:36 AM
Hi Mahesh,
   Hope you are well.

I have question that is if I set the button "Get Data" from another application then your existing gridview page show those data?????

Comment posted by Kamal on Tuesday, August 21, 2012 2:43 AM
Hi Mahesh,
Can you please suggest me, how to do it in asp.net.
I just want to implement in asp.net, as I got data from client1, I want to send it to client2(without client2 request on server)
Comment posted by mostafa Shafeian on Wednesday, August 22, 2012 11:07 PM
hi
This is very nice and useful for me
Thanks alot
Comment posted by venkat on Monday, March 18, 2013 8:47 AM
This example works fine in windows forms. When I tried in asp.net, didn't work as expected. The callback value didn't update my controls (say label text)
Comment posted by Venkat on Monday, March 18, 2013 8:52 AM
Here is my full asp.net code

public delegate void updateFormDelete();

    public partial class CallbackForm : System.Web.UI.Page
    {  
        SampleServiceCallback callBack = null;

        protected void btnTCP_Click(object sender, EventArgs e)
        {
            updateFormDelete del = new updateFormDelete(setData);

            callBack = new SampleServiceCallback(del);
            InstanceContext ic = new InstanceContext(callBack);
            SampleService1Client client = new SampleService1Client(ic, "Service1_TCP");
            client.GetData(10);  
            Label1.Text = callBack.LabelValue;//this is wrong place even with the win forms.
        }

        public void setData()
        {
           Label1.Text = callBack.LabelValue; ///No error but the value not seen updated
           Response.Write(callBack.LabelValue);//throws expection as Response object is null
        }
    }

    public class SampleServiceCallback : ISampleService1Callback
    {
        public string LabelValue { get; set; }
        public updateFormDelete mydel = null;

        public SampleServiceCallback(updateFormDelete mydelegate)
        {
            mydel = mydelegate;
        }

        public void NotifyData(string value)
        {
            LabelValue = value;
            mydel.Invoke();
        }
    }
Comment posted by Swati on Tuesday, April 16, 2013 8:09 AM
Nice article, I want to send data to client application through WCF without client request requesting. How can that be done can that be done through same way as above
Comment posted by Reza on Friday, June 28, 2013 3:32 PM
It is the best , thank you mahesh
Comment posted by suhas on Monday, July 29, 2013 1:16 AM
Hi All,

I am new to WCF and trying to understand its feature. I have gone through all of the code given here, but i am not able to make out what purpose does the callback do here, as it is just sending back information only after a response has been sent by client, same thing can be achieved by hitting a normal web service.

Actually I am building a real time application where data at client will be refreshred every 10 seconds. what i want is , instead of every client application hitting the database every 10 seconds , I want the service to hit database get the data and pass it on to all the clients . Can this be achieved?
Comment posted by suhas on Monday, July 29, 2013 1:53 AM
Hi All,

I am new to WCF and trying to understand its feature. I have gone through all of the code given here, but i am not able to make out what purpose does the callback do here, as it is just sending back information only after a response has been sent by client, same thing can be achieved by hitting a normal web service.

Actually I am building a real time application where data at client will be refreshred every 10 seconds. what i want is , instead of every client application hitting the database every 10 seconds , I want the service to hit database get the data and pass it on to all the clients . Can this be achieved?
Comment posted by Pankaj on Friday, October 11, 2013 8:38 AM
Hi Suhas,

I am also trying to develop same kind app in WCF.. where  service would hit database get the data and pass it on to all the clients.
Please let me know if you have got any solution .

Regards,
Pankaj  
Comment posted by Pranav Thakur on Monday, December 16, 2013 11:20 PM
Let me explain in detail about my requirement:I need to transfer data to a client through WCF services. Data can be of 1MB to 1GB size to be transferred.
So, what can I do, I can pull Data from the database and provided to the client through WCF service.Client can then add it in its local database. How can I manage transferring large data? I want to be able to resume the process if it fails in the middle of the transfer. How can I know if the Client local database has been updated or not.Should I be using a WCF streaming?
Thanks.
Comment posted by Pranav Thakur on Tuesday, December 17, 2013 12:08 AM
Let me explain in detail about my requirement:I need to transfer data to a client through WCF services. Data can be of 1MB to 1GB size to be transferred.
So, what can I do, I can pull Data from the database and provided to the client through WCF service.Client can then add it in its local database. How can I manage transferring large data? I want to be able to resume the process if it fails in the middle of the transfer. How can I know if the Client local database has been updated or not.Should I be using a WCF streaming?
Thanks.

Post your comment
Name:  
E-mail: (Will not be displayed)
Comment:
Insert Cancel