65.9K
CodeProject 正在变化。 阅读更多。
Home

WCF 服务, 该服务将内容推送到 Silverlight 应用程序 [推送通知]

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.40/5 (7投票s)

2011年4月28日

CPOL

5分钟阅读

viewsIcon

38621

downloadIcon

1085

本文描述了一个WCF服务,该服务可以将内容推送到Silverlight应用程序。

Sample Image

引言

“推送通知”这个词已经存在很久了。几乎所有制造的智能手机都有启用推送通知的选项。“PUSH”与“PULL”相反。这意味着服务器不是从服务器拉取内容或向服务器请求内容,而是只要有更新可用,服务器就会推送内容或发送响应。在手机上,这项技术非常省电。在Web技术中,它大大节省了服务器请求流量。互联网上有大量关于实现此技术的文章,但我发现MSDN是最好的。因此,我继续努力,让MSDN教程对初学者来说更容易。请记住,这是一篇初学者文章,但实现真实应用程序的想法围绕着这个。你可以尽力重新编码。

在这里,我们将看到一个Silverlight应用程序请求雅虎!的股票价格。服务器将开始推送最新的股票价格。股票价格是随机数字。该应用程序基于一些假设。

背景

作为新手,您必须了解WCF、基本Silverlight以及推送通知等术语。请参考维基百科了解定义。

使用代码

我使用.NET Framework 4.0来开发示例。如果您使用的是早期版本,则可能需要更改一些代码。

  1. 转到新项目并创建一个WCF服务应用程序。首先要添加的是对Polling Duplex DLL的引用。您需要在“添加引用”窗口中浏览到%Program Files%\Microsoft SDKs\Silverlight\v3.0\Libraries\Server\System.ServiceModel.PollingDuplex.dll。请仔细看,我们正在从libraries\server文件夹引用轮询双工DLL。
  2. 右键单击项目并添加一个新项“接口”。您可以将其命名为IService1.cs
  3. 您必须在标题区域包含这些:using System.ServiceModel;using System.ServiceModel.Web;
  4. 复制并粘贴以下代码。基本上,我们在该接口中定义了两个接口。IsOneWay=true是一种消息传递模式,意思是“调用并忘记”,与“请求-响应”相反。
  5. 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. 转到service1.svc.cs。如果不存在,请在标题中包含这些:using System.ServiceModel;using System.ServiceModel.Web;。您还必须包含:using System.Threading;
  7. 将以下代码复制并粘贴到您的service1.svc.cs中。RequestPrice(string stocksyb)方法将从Silverlight调用,并带有stockname参数。此时,列表中有三只股票将被搜索并返回一个随机价格。搜索是通过LINQ完成的,因此您需要将System.Linq作为引用。PushDatatimercallback委托每秒调用一次。client.PushPrices(_i);是将在客户端推送内容的方法。
  8. 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. 下一步是创建一个类文件。因此,添加一个新类并将其命名为PollingDuplexServiceHostFactory.cs。添加以下内容
  10. 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. 转到您的Service.svc文件的标记代码。右键单击文件->查看标记。用以下代码替换它
  12. <%@ServiceHost language="c#" Debug="true" 
        Factory="DuplexService.PollingDuplexServiceHostFactory"%>
  13. 构建服务并查看它是否正确显示。如果您正在使用开发服务器,请确保在完成客户端应用程序之前,动态端口保持不变。就是这样;WCF端编码已完成。现在让我们创建客户端应用程序。
  14. 我们将使用Silverlight开发客户端应用程序。您必须已安装SDL。向同一解决方案添加新项目。选择Silverlight应用程序。
  15. 第一步是为客户端添加轮询双工DLL的引用。添加引用并从中浏览%Program Files%Microsoft SDKs\Silverlight\v3.0\Libraries\Client\System.ServiceModel.PollingDuplex.dll
  16. 请仔细看,这与之前的不同。此DLL是从Libraries\Client文件夹引用的。

  17. 现在您需要添加服务引用。右键单击服务引用->添加服务引用。单击“发现”。您应该看到Service.svc。将命名空间输入为StockService,然后按OK。
  18. 转到您的默认XAML页面“MainPage.xaml”。添加两个TextBlock。将它们命名为“info”和“reply”。

  19. 在您的MainPage.xaml.cs的标题中添加引用:using System.ServiceModel;using System.ServiceModel.Channels;using SilverlightApplication2.StockService;
  20. 复制并粘贴以下代码
    • EndpointAddress应包含您的服务的URI。在开发服务器上工作时,不要忘记检查当前端口。
    • 代理对象是我们服务引用命名空间“StockService”的对象。
    • 事件处理程序将处理来自服务的值。该处理程序处理proxy_PushPricesReceived方法。
    • e对象是从服务返回的(_i)值。

    您可以看到我们正在请求雅虎的价格,因为它存在于我们的列表中。如果我们输入其他内容,服务器将响应“无效的股票请求”。

    namespace SilverlightApplication2
    {
        public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
                EndpointAddress address = 
                  new EndpointAddress("https://: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. 生成项目并导航到Silverlight应用程序文件夹\SilverlightApplication2\Bin\Debug。复制SilverlightApplication2.xap文件并将其粘贴到您的WcfService1\ClientBin文件夹中。您需要创建ClientBin文件夹。每次在.xamlxaml.cs文件中进行更改时,都需要执行此操作。
  22. 在WCF项目中,添加一个新HTML文件。将以下代码复制并粘贴到body标签中
  23. <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. 生成所有内容。将HTML页面设置为启动文件并运行项目。该应用程序将请求雅虎的价格,服务器将每秒推送一次内容。
  25. 使用Fiddler查看服务器的响应。
© . All rights reserved.