使用轮询双工和线程多播命令的 Silverlight/WCF 示例
即使某些客户端已断开连接,也能向客户端发送多播命令,并通过使用线程发送命令来避免阻塞。
引言
此示例使用具有轮询双工绑定的 WCF 服务作为 Silverlight 客户端的聊天服务器。起始页 (Default.aspx) 将启动四个聊天应用程序实例,以便每个客户端都可以相互发送消息。
此应用程序与许多其他 Silverlight 聊天示例的区别在于,WCF 服务使用线程向客户端发出回调。请注意,轮询双工绑定实际上从未打算用作多播,它也不是真正可扩展的。但是,此解决方案为此问题提供了一个合理的解决方法。
背景
轮询双工绑定不适合向客户端发送多播消息,因为如果客户端不再连接到服务并且向该客户端发出回调,则服务将挂起,直到超时期限过期。此示例为每个客户端回调创建一个线程,以便如果回调挂起,服务的其余部分将继续运行。
此服务的关键是在绑定部分使用inactivityTimeout
属性。在此示例中,此值设置为 10 秒。客户端使用计时器根据名为ClientPingInterval
的appSetting
值(默认为 1 秒)调用名为ImAwake
的函数。每次调用ImAwake
时,它都会重置该客户端的服务“非活动时钟”并重新开始。
每个客户端通过调用ConnectAsynch
函数启动服务。这将创建一个clsSession
类并将其添加到ActiveSessions
字典中,以便服务可以跟踪已连接的客户端。当客户端由于用户关闭浏览器或某些网络错误而在 10 秒后超时时,clsSession
类将自动释放并从ActiveSessions
字典中删除。此外,还会通知每个客户端该客户端已超时,以便他们可以从已连接用户列表中删除该用户。此示例使用可观察集合和集合视图源模式来在客户端中提供已连接用户的排序列表。
线程回调的工作方式如下。每个clsSession
对象都有一个子/函数,用于需要发送给客户端的任何回调。该例程创建一个新的ThreadedCallBack
类实例,然后调用相应的函数并传入任何需要的参数。然后,ThreadedCallBack
类将创建一个在后台运行的新线程,然后在try
/catch
语句中执行客户端回调。由于它是线程化的,因此如果客户端不再连接,服务将不会挂起。
使用代码
首先,您可能需要在ConsoleServiceHost和SilverlightSample.Web项目中添加对System.ServiceModel.PollingDuplex
的引用。这些通常可以在C:\Program Files\Microsoft SDKs\Silverlight\v3.0\Libraries\Server\目录中找到。接下来,您需要决定是想从 IIS 还是从控制台主机运行 WCF 服务。
如果要从 IIS 运行,则在SilverlightSample.Web项目中修改web.config文件,并将UseConsoleService
的值更改为 false,并将SilverlightSample.Web项目设置为启动项目。不要忘记确保Default.aspx设置为起始页。
我更喜欢从控制台主机运行我的 WCF 服务,因为它是一种非常有用的显示调试消息的方法。要使用控制台主机,请将UseConsoleService
的值设置为 true,然后右键单击解决方案,选择“属性”页,并将“多个启动项目”设置为 true,然后设置ConsoleServiceHost和SilverlightSample.Web项目以运行。
请注意,无论您决定使用哪个项目,都将服务模型绑定拆分为三个单独的文件(behaviors.config、bindings.config和services.config)。
Default.aspx启动页将启动四个客户端浏览器,以便您可以试验该应用程序。您会注意到Default.aspx页面使用一些会话变量,然后这些变量在SilverlightSampleTestPage.aspx页面中使用,以便它知道在哪里可以找到 WCF 服务的 URL。
我当然没有解释此示例的每一个细节,因此请随时向我发送您的问题,我将尽力回答。