Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / XAML

WCF service that will push content into a Silverlight application [Push notification]

3.40/5 (7 votes)
28 Apr 2011CPOL5 min read 38.2K   1.1K  
The article describes the development of a WCF service that will push content into a Silverlight application.

Sample Image

Introduction

Push notification is a term that has been around a lot. Almost every SmartPhone manufactured has an option for enabling push notification. The word 'PUSH' is a contrast to 'PULL'. It means rather than pulling the content from the server or requesting from the server, the server pushes the content or sends the response as soon as an update is available. On mobiles, this technology is a great battery saver. In web technologies, it saves a lot of server request traffic. There are tons of articles available on the internet about implementing this technique, but I found MSDN the best. Therefore, I went ahead and made the MSDN tutorial even easier for beginners. Remember, this is beginners article, but the idea of implementing a real life application stays around this. You can recode it as best as you can.

Over here, we are going to see a Silverlight application requesting for stock prices of Yahoo! The server will start pushing the latest stock prices. The stock prices are random numbers. The application is based on some assumptions.

Background

As a newbie, you must be aware of WCF, basic Silverlight, and terms like Push notification. Please refer to Wikipedia for the definitions.

Using the code

I have used .NET Framework 4.0 to develop the example. You might have to change some code if you are using an earlier version.

  1. Go to the new project and create a WCF Service Application. The first thing to add is the reference to the Polling Duplex DLL. You need to browse in your Add References window to %Program Files%\Microsoft SDKs\Silverlight\v3.0\Libraries\Server\System.ServiceModel.PollingDuplex.dll. Please look carefully, we are referencing the polling duplex DLL from the libraries\server folder.
  2. Right click the project and add a new item 'Interface'. You can name it IService1.cs.
  3. You must include these in the header area--> using System.ServiceModel; and using System.ServiceModel.Web;.
  4. Copy-paste the following code. Basically, we have defined two interfaces within this interface. IsOneWay=true is a messaging pattern which means 'call and forget' in contrast to 'request-response'.
  5. C#
    namespace DuplexService
    {
        [ServiceContract(Namespace="Silverlight", 
              CallbackContract = typeof(IDuplexClient))]
        public interface IDuplexService
        {
            [OperationContract(IsOneWay = true)]
            void RequestPrice(string stocksyb);
        }
    
        [ServiceContract]
        public interface IDuplexClient
        {
            [OperationContract(IsOneWay = true)]
            void PushPrices(string p);
    
        }
    }
  6. Go to service1.svc.cs. Include these in the header if they do not exist: using System.ServiceModel; and using System.ServiceModel.Web;. You must also include: using System.Threading;.
  7. Copy-paste the following code in your service1.svc.cs. The RequestPrice(string stocksyb) method is going to be called from Silverlight with the stockname parameter. At this point, we have three stocks in the list which will be searched and responded with a random price. The searching is done via LINQ, therefore you need to have System.Linq as a reference. PushData is being called by the timercallback delegate every second. client.PushPrices(_i); is the method that is going to push the content on the client.
  8. C#
    namespace DuplexService
    {
        public class StockService: IDuplexService
        {
            IDuplexClient client;
            Random num = new Random();
    
    
            public void RequestPrice(string stocksyb)
            {
                // Grab client callback channel.
                
                client = OperationContext.Current.GetCallbackChannel<IDuplexClient>();
    
                List<string> stocklist = new List<string>();
                stocklist.Add("Yahoo");
                stocklist.Add("Microsoft");
                stocklist.Add("Google");
    
    
                var query = from s in stocklist where s == stocksyb select s;
              
                var result = query.SingleOrDefault();
    
                if (result != null)
                {               
    
                     //Pretend service is pulling latest stock prices.
                    using (Timer timer = 
                       new Timer(new TimerCallback(PushData), stocksyb, 1000, 1000))
                    {
                        Thread.Sleep(System.Threading.Timeout.Infinite);                   
    
                    }               
    
                }
                else
                {
    
                    client.PushPrices("Invalid Stock Request");
                }
            
            
            }       
    
            private void PushData(object o)
            {              
                
                //Random stock prices between 200 and 205.
                //This is where you can bring in your content from a datasource
                string _i = num.Next(201,205).ToString();           
    
    
                // Send price to client
                client.PushPrices(_i);
    
            }
        }  
    }
  9. The next step is to create a class file. Therefore, add a new class and name it PollingDuplexServiceHostFactory.cs. Add the following content:
  10. C#
    using System;
    using System.ServiceModel;
    using System.ServiceModel.Activation;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Description;
    using DuplexService;
    
    namespace DuplexService
    {
        public class PollingDuplexServiceHostFactory : ServiceHostFactoryBase
        {
            public override ServiceHostBase CreateServiceHost(string constructorString,
                Uri[] baseAddresses)
            {
                return new PollingDuplexSimplexServiceHost(baseAddresses);
            }
        }
    
        class PollingDuplexSimplexServiceHost : ServiceHost
        {
            public PollingDuplexSimplexServiceHost(params System.Uri[] addresses)
            {
                base.InitializeDescription(typeof(StockService), 
                             new UriSchemeKeyedCollection(addresses));
               // base.Description.Behaviors.Add(new ServiceMetadataBehavior());
            }
    
            protected override void InitializeRuntime()
            {
                // Add an endpoint for the given service contract.
                this.AddServiceEndpoint(
                    typeof(IDuplexService),
                    new CustomBinding(
                        new PollingDuplexBindingElement(),
                        new BinaryMessageEncodingBindingElement(),
                        new HttpTransportBindingElement()),
                        "");
    
                // Add a metadata endpoint.
                this.AddServiceEndpoint(
                    typeof(IMetadataExchange),
                    MetadataExchangeBindings.CreateMexHttpBinding(),
                    "mex");
    
                base.InitializeRuntime();
            }
        }
    }
  11. Go to the markup code of your Service.svc file. Right click File->View markup. Replace it with the following code:
  12. XML
    <%@ServiceHost language="c#" Debug="true" 
        Factory="DuplexService.PollingDuplexServiceHostFactory"%>
  13. Build the service and see if it displays correctly. If you are working on the development server, then make sure that your dynamic port stays the same till we complete our client application. This is it; we are done with the WCF side coding. Now let's make the client application.
  14. We are going to develop the client application in Silverlight. You must have the SDL installed. Add a new project to the same solution. Select Silverlight Application.
  15. The first step is to add the reference to the client side Polling Duplex DLL. Add a reference and browse to it from %Program Files%Microsoft SDKs\Silverlight\v3.0\Libraries\Client\System.ServiceModel.PollingDuplex.dll.
  16. Watch carefully, it's not the same as the previous one. This DLL is being referenced from the Libraries\Client folder.

  17. Now you need to add the service reference. Right click on the service reference->Add Service Reference. Click Discover. You should see Service.svc. Enter the namespace as StockService and press OK.
  18. Go to your default XAML page "MainPage.xaml". Add two TextBlocks. Name them 'info' and 'reply'.

  19. Add references in the header of your MainPage.xaml.cs: using System.ServiceModel;, using System.ServiceModel.Channels;, using SilverlightApplication2.StockService;.
  20. Copy paste the following code:
    • The EndpointAddress should contain the URI to your service. Don't forget to check your current port while you are working on your development server.
    • The proxy object is the object of our service reference namespace "StockService".
    • The event handler will handle the incoming values from the service. The handler handles the proxy_PushPricesReceived method.
    • The e object is the (_i) returned value from the service.

    You can see we are requesting for Yahoo!'s price as it exists in our list. If we enter something else, then the server will respond with an "invalid stock request".

    C#
    namespace SilverlightApplication2
    {
        public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
                EndpointAddress address = 
                  new EndpointAddress("http://localhost:1582/Service1.svc");            
                PollingDuplexHttpBinding binding = new PollingDuplexHttpBinding();
                DuplexServiceClient proxy = new DuplexServiceClient(binding, address);
                proxy.PushPricesReceived += 
                  new EventHandler<PushPricesReceivedEventArgs>(
                  proxy_PushPricesReceived);
    
                //the only allowed stocks are Yahoo,Microsoft,Google.
                //else the service will return 'Invalid Stock Request'
                string stocksymb = "Yahoo";
                
                proxy.RequestPriceAsync(stocksymb);
                info.Text = "Fetch price for " + stocksymb + 
                                Environment.NewLine + Environment.NewLine;
    
            }
    
            void proxy_PushPricesReceived(object sender, PushPricesReceivedEventArgs e)
            {
                reply.Text = "Current Market Price :  ";
                reply.Text += e.p;
            }
        }
    }
  21. Build the project and navigate to the Silverlight application folder, \SilverlightApplication2\Bin\Debug. Copy the SilverlightApplication2.xap file and paste it in your WcfService1\ClientBin folder. You will need to create the ClientBin folder. You will need to do this every time you make changes in your .xaml and xaml.cs file.
  22. In your WCF project, add a new HTML file. Copy paste the following code in the body tag:
  23. XML
    <div id="silverlightControlHost">
        <object data="data:application/x-silverlight-2," 
                 type="application/x-silverlight-2" width="100%" height="100%">
          <param name="source" value="ClientBin/SilverlightApplication2.xap"/>
          <param name="onError" value="onSilverlightError" />
          <param name="background" value="white" />
          <param name="minRuntimeVersion" value="3.0.40818.0" />
          <param name="autoUpgrade" value="true" />
          <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40818.0" 
                        style="text-decoration:none">
              <img src="http://go.microsoft.com/fwlink/?LinkId=161376" 
                      alt="Get Microsoft Silverlight" style="border-style:none"/>
          </a>
        </object><iframe id="_sl_historyFrame" 
              style="visibility:hidden;height:0px;width:0px;border:0px">
        </iframe>
    </div>
  24. Build everything. Set your HTML page as your start up file and run the project. The application will request for Yahoo!'s price and the server will push the content every second.
  25. Use Fiddler to see the responses from the server.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)