Silverlight和推送通知

时间:2009-03-12 21:07:36

标签: silverlight notifications push

我正在为远程乐器创建Silverlight 2用户界面。在不同站点有两个并发用户与仪器(仪器和远程科学家的操作员)以及任何不与之交互的观察者用户进行交互,只是观看。但是,每当两个活动用户中的一个发生变化时,这些变化必须立即反映在所有用户的UI中,例如,平移或缩放图像或注释或选择图像的一部分,将项目添加到列表框中显示的集合中。在客户端中,我使用可观察的集合,这些集合很容易反映该用户所做的更改,但是很难看到其他用户所做的更改。我可以从每个客户端轮询更改,但推送通知等更好。我已经广泛搜索了一些例子,但没有找到任何我需要的东西。 Silverlight与WCF服务交互存在各种安全问题,这意味着许多潜在的示例都无法正常工作。我基本上没有时间在这个项目上,需要快速帮助。有没有人有任何关于如何做到这一点的合适简单例子的建议?我是一名经验丰富的开发人员,但不得不自学Silverlight和WCF服务,我所在地区没有人知道这些。即使你已经完成了相当多的ASP.NET工作,我也不是web / Javascript专家。感谢。

8 个答案:

答案 0 :(得分:10)

Silverlight 2支持推送通知,使用新的WCF PollingDuplexHttpBinding支持。 Silverlight SDK(one for Silverlight app one for WCF server)安装了两个程序集。

我有一个few blog posts and a full sample application,演示了如何从控制台应用服务器“推送”库存更新,该服务器将WCF服务自托管到已连接的客户端。它还显示了每个客户端如何针对Stock添加注释并使这些注释同步(从服务器推送)到所有其他连接的客户端。

该示例的最新版本(第4部分)显示了如何使用两个服务器端点同步Silverlight和WPF客户端之间的推送更新,如下所示:

using System;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace StockServer
{
    public class StockServiceHost : ServiceHost
    {
        public StockServiceHost(object singletonInstance, params Uri[] baseAddresses)
            : base(singletonInstance, baseAddresses)
        {
        }

        public StockServiceHost(Type serviceType, params Uri[] baseAddresses)
            : base(serviceType, baseAddresses)
        {
        }

        protected override void InitializeRuntime()
        {
            this.AddServiceEndpoint(
                typeof(IPolicyProvider),
                new WebHttpBinding(),
                new Uri("http://localhost:10201/")).Behaviors.Add(new WebHttpBehavior());

            this.AddServiceEndpoint(
                typeof(IStockService),
                new PollingDuplexHttpBinding(),
                new Uri("http://localhost:10201/SilverlightStockService"));

            this.AddServiceEndpoint(
                typeof(IStockService),
                new WSDualHttpBinding(WSDualHttpSecurityMode.None),
                new Uri("http://localhost:10201/WpfStockService"));

            base.InitializeRuntime();
        }
    }
}

WPF客户端连接到WSDualHttpBinding端点,Silverlight客户端连接到同一WCF服务的PollingDuplexHttpBinding端点。该应用程序还显示了如何处理Silverlight客户端访问策略要求。

客户端(Silverlight或WPF)可以在其UI中添加针对Stock的注释,这些注释将传播回服务器以推送到所有其他客户端。这表明了在任一方向上的沟通,并希望能够执行您的应用程序所需的所有必要通信。

您可以看到demo application running here的屏幕截图。

答案 1 :(得分:6)

并不是说我会以粉丝男孩的方式推动Flex,但事实上这就是我们常规构建到所有基于Flex的应用程序中的那种架构。以下是我们在Flex上所做的事情 - 毫无疑问,它可以适当地转换为Silverlight:

我们采用三种成分并将它们整合在一起以实现此功能:

  1. Comet模式(与服务器推送通知的HTTP兼容方式 - 在维基百科上查看更多信息)
  2. JMS消息传递主题(发布/订阅者队列)
  3. Adob​​e BlazeDS servlet
  4. 后一项实现了Comet模式,支持AMF对象编组(Adobe的ActionScript3对象的二进制序列化格式),以及与JMS队列或主题的桥接。在桥接到主题时,可以将在浏览器中运行的多个Flex客户端代理为JMS主题的订阅者。因此,如果任何客户端发布消息(或服务器端代码发布到主题中),则所有客户端订阅者都将通过BlazeDS和Comet Pattern实现将消息推送给他们。

    有效地,您需要找到或编写一个完成BlazeDS功能的组件。您可能还需要实现一些与此服务器端组件的Comet模式交互的客户端代码。

    WCF是否支持Comet模式和双向消息传递?特别是在符合HTTP和端口80或端口443的情况下,SSL。看起来你已经调查过这个并没有找到任何用于双向消息传递的东西。所以你可能需要卷起袖子做一些编码。

    关于将服务器推送到Web应用程序的一些注意事项:

    BlazeDS支持实现Comet模式的两种主要模式(实际上有第三种轮询选项,但忽略它):

    1. 长轮询
    2. HTTP流媒体
    3. 您应该发现的长轮询广告对大多数网络浏览器更为普遍支持。因此,您可以简化为最初支持。或者你可以花时间让你的客户端代码首先尝试HTTP流媒体,并在必要时切换到长轮询。

      对于可以提供发布/控制能力的消息代理,您可以考虑使用ActiveMQ JMS。它是开源的,免费的,有积极的社区支持(你也可以购买支持)。另外,您可以使用NMS作为.NET客户端进行集成。

      让消息代理位于中间层实际上很重要,因为它将是一个安全放置消息的地方。如果您的客户正在进行长轮询,那么您不希望他们在实际连接时间隔期间错过任何新消息。

      在高流量场景中需要考虑的另一件事(数百或数千个客户端,例如互联网上的网站),您需要采用可扩展的Comet模式方法。

      在Flex / Java世界中,BlazeDS servlet(开源)已经过修改,可以与异步模型一起使用。在Java中,可以构建套接字侦听器以使用NIO通道和Java Concurrency Executor线程池。 Tomcat Web服务器具有NIO侦听器并支持异步Servlet 3.0事件。但是,特别是BlazeDS已被修改,以便与Jetty Web服务器一起使用。最重要的是,这种异步方法的可扩展性意味着可以增强单个物理Web服务器,以支持最多约20,000个并发Comet风格的客户端连接。

      我已经有一段时间了,因为我已经完成了严肃的.NET编程,但习惯了io功能与Java 1.1非常相似,只是具有异步结果处理程序功能。但是,这与通过Java NIO通道创建异步套接字侦听器不同。 NIO通道实现可以使用相对较小的线程池支持数百到数千个套接字连接。但是C#和.NET已经经历了两到三次重大转变 - 可能已经添加了与NIO频道相当的新io功能。

答案 2 :(得分:3)

我只是想澄清PollingDuplexHttpBinding没有实现'true'推送通知,因为它显示了它的名字(轮询)。来自msdn documentation

  

配置此绑定后,Silverlight客户端会定期轮询网络层上的服务,并检查服务要在回调通道上发送的任何新消息。该服务将客户端回调通道上发送的所有消息排队,并在客户端轮询服务时将其传递给客户端。

然而,它比传统的轮询Web服务的方式更有效,因为在每次轮询之后,服务器将保持通道打开一段时间(比如1分钟),如果消息在那个时间到达,它将会直接将“推送”消息发送给客户端。客户端必须反复更新其连接,因此可以轮询该服务。

如果你想用silverlight实现真正的推送通知,我相信你需要使用套接字,我建议你阅读Dan Wahlin关于这个主题的一些博文。

答案 3 :(得分:2)

可替换地,

如果您想要一个没有代理,桥接或网络服务器的原生Silverlight API,您可以使用my-Channels中的Nirvana作为您的消息传递中间件。从我的频道和他们的展示网站查看Nirvana。 (抱歉,我是新用户,无法提交链接):

亚历

答案 4 :(得分:2)

编辑:它实际上工作正常。我被一个闭包中的“隐藏变量”严重咬了一下:(

我使用了PollingDuplex for SL2,我认为它尚未准备好进行生产。

我的主要问题是它不会在同一台机器上的客户端上进行区分。如果我运行2个客户端,那么其中一个客户端将无法再轮询服务器并且将超时。有一个SessionId对于2个客户端是不同的,但它在客户端被忽略。

同样,如果我杀了一个客户端,然后再创建一个新客户端,那么新客户端将从之前的客户端获得推送更新一段时间。

是否有人遇到过相同的问题或是否已在SL3中修复?

实际上我运行了一些演示代码,并意识到由于某种原因你必须指定InstanceContextMode和InstanceMode,以便服务是基于会话而不是单身(据我所知)。我提取的简单演示代码中存在明显的性能问题。

非常遗憾的是,没有记录这种行为。

答案 5 :(得分:1)

我的组织发现Silverlight 2.0 / WCF推送实现有点“没有为黄金时间做好准备”,至少对于我们计划用它来做什么。

我们最终选择了XMPP / Jabber,因为它是一个形状更好的野兽,你可以在Silverlight中轻松实现它,只需从互联网上获取一些资源。

我相信Silverlight 3.0将实现更新/更完善的推送实现,从我从公开信​​息中可以看出。

答案 6 :(得分:0)

PollingDuplexHttpBinding可能是最优雅的方式。

一种较少涉及的替代方案是使用Silverlight客户端的TCP套接字。每当其中一个Silverlight客户端需要推送更新时,您就可以向其发送一条TCP消息,其中包含需要调用的WCF服务的名称或其他一些轻量级信息。

我将这种方法用于应用程序并且运行良好。

答案 7 :(得分:0)

网站http://www.udaparts.com/document/Tutorial/slpush.htm

的一个更简单,更强大的解决方案