Asp.net 构建可扩展的的Comet Web 应用(二)

简介: 说明 如果你已经阅读了我之前的一篇文章《Asp.net构建可扩展的的Comet Web 应用》。你应该能够理解我将要写的内容。我解释了Comet技术并且解释了怎样用asp.net构建具有可扩展性的应用。

说明

如果你已经阅读了我之前的一篇文章《Asp.net构建可扩展的的Comet Web 应用》。你应该能够理解我将要写的内容。我解释了Comet技术并且解释了怎样用asp.net构建具有可扩展性的应用。然而,我认为之前的的一篇文章写得有点像主线。它展示了足够的技术,但是没有足够包含任何有用的代码。因此,我想我需要写一个API来将之前一篇文章中的功能封装起来。封装为一系列整齐的类,让它们可以被包含到一个通常的web项目中,给你机会去扩展和测试它。

我将不涉及太多关于线程模型的具体细节。因为在之前的一篇文章中涉及了太多关于它的内容。我仅仅讲解涉及到API并且怎样在你的web应用程序中使用它。

我决定写一个轻量级的发送消息的API,它类似于Bayeuxprotocol【Bayeux是在和web服务器间提供低时延、传输异步消息的协议(主要基于HTTP)】交换信息的方式。但是,它没有它没有一个基于改协议的实现当我相信它能够矫枉过正,为了那些被用来需要用这些API工作的需求。并且它也仅仅只是一个草案。

我的原文将我会给出一个小游戏。不巧的是,我觉得用一个简单的聊天程序来说明它可能更加容易。这个程序使用一个Comet通道来接受信息,用一个WCF服务来发送信息。

基本的聊天程序:


术语表

下面是我这篇文章中使用的列表,以及他们的描述。

通道:这是一个Comet客户端能够连接到的结束点。任何发送到客户端的信息必须被转交给通道传输。

超时:当一个客户端已经连接到一个通道,并且过了预定义的一段时间内,还没有收到任何的消息。当超时的时候客户端可以重新建立连接。

闲置客户端:这是一个客户端没有连接到服务器的时限。一个闲置的客户端在一个预设的时间后将被断开。

消息:通过一个通道发送给一个客户端的JSON格式的消息。

订阅:一个客户端被订阅到一个通道。他们被连接并且准备接受消息。

项目的代码

项目的代码包含所有的能够在你的asp.net项目中使用Comet类。代码和原文中设计的代码非常接近。但我扩展了功能,使得能够在客户端和服务端传输通常的消息。

控制Comet主要的类是CometStateManager。这个类管理单个的通道。这个类使用ICometStateProvider接口的一个实例以一种特别的方式来为你的应用程序管理状态。在API中,有一个内建InProcCometStateProvider的实现,用来在服务器的内存中存储状态。很显然,这不是实现负载均衡环境的一个好做法。但你可以实现一个自定义的提供程序(provider),使用数据库或者一个自定义的状态服务器。

为了向外部暴露你的通道,需要用一个IHttpAsyncHandler的实现来包装它。我最终试图使用一个WCF的异步模型。但发现它不会释放asp.net工作线程,如同使用异步handler一样。这有点可惜,这并不是期望的。

下面的代码展示了你应该怎样去建立一个IHttpAsyncHandler来为你的Comet通道提供一个结束点。


上面的代码足够简单。我们有一个CometStateManager类的静态实例。它被用来构建ICometStateProvider的实例。在这个例子中,我们使用一个内置的InProcCometStateProvider的实现。

这个类其余的实现是简单得将BeginProcessRequest和EndProcessRequest方法映射到CometStateManager 类实例的BeginSubscribe和EndSubscribe方法。我们也需要在web.config中配置handler才能使用它。


这个通道现在已经可以被客户端订阅了

CometClient类

通道需要与客户端保持连接。每一个客户端都代表一些被CometClient的实例排序的缓存。我们不希望任何旧的客户端连接着服务器或者任何没有被认证的客户端注册通道。所以我们希望实现一种授权和认证机制。也许是asp.net标准的 Form认证,或者也许是一个WCF调用一个服务来验证凭据,并且在我们的通道中实例化一个客户端。

下面的代码展示了default.aspx页面的登录操作:


我们没有验证密码或任何其他的东西,我们只是在页面上直接输入用户名,并且用它来区分不同的客户端。一个Comet客户端有两个token供API使用:

PrivateToken这个token是客户端私有的,被用来注册消息到客户端。

PublicToken这个token被用来区分是哪一个客户端。它通常在发送消息到一个特殊的客户端时被使用。

我们使用一个公共令牌和一个私有令牌的原因是,私有令牌能够被用来注册一个通道以及从别的用户那里接受消息。我们不想任何其他的客户端能够隔离原本的客户端(例如我们不希望消息欺骗)。出于这个原因,如果我们想在两个客户端之间发送消息我们使用公共令牌。

为了简单起见,我已经在客户端包含了一个DisplayName的属性来存储用户名。

为了在客户端建立一个通道,你需要调用InitializeClient。在上面有显示。这个方法携带了下面的一些参数:

publicToken – 客户端公共令牌

privateToken – 客户端私有令牌

displayName – 客户端显示名称

connectionTimeoutSeconds – 连接超时时间

connectionIdleSeconds- 在服务器杀掉一些闲置客户端从而等待一个客户端重新连接的秒数。

上面的例子中,InitializeClient会调用。从表单中指定用户名作为公共令牌,私有令牌以及显示名称。这不是非常的安全,但对于一个Demo来说已经足够了。为了使它更加安全,我本可以产生一个GUID来作为私有令牌。并且使用公共令牌作为用户名。

InitializeClient将通过ICometStateProvider被调用。一个新的InitializeClient实例化了CometClient类。并且期望它被存储在缓存中。

随着CometClient的可访问,客户端可以使用它们自己的私有令牌来订阅通道。

客户端 JavaScript

为了实现客户端的功能,有一个文件在项目中,Scripts/AspNetComet.js包含了所有的需要订阅通道的js(以及公有的JSON转换器)。为了使一切变得简单一点,我在CometStateManager中包含了一个静态方法来调用RegisterAspNetCometScripts。它接受一个带有参数的页面并且在页面上注册了脚本。


随着它被调用,我们就能够很自由得使用我们能够使用的客户端API。下面的例子摘自项目中的chat.aspx。并且展示了一旦一个客户端被实例化,你应该怎样订阅一个通常的通道。


客户端API所有的功能都被包裹到一个被叫做AspNetComet的JavaScript类中。这个类的一个实例被用来跟踪一个已连接的客户端的状态。被要求订阅的是Comet结束端的handler的URL。CometClient的私有令牌,以及一个别名被用来区别客户端通道。一旦我们构建一个AspNetComet的实例,我们可以在Comet的生命周期内定义一系列的handler以供在特殊时刻调用。

addTimeoutHandler当一个客户端等待过了一个预定的事件并且没有接收到消息调用该handler。

addFailureHandler当一个Comet调用失败,其中一个失败的例子就是Comet客户端没有被连接,调用该handler。

addSuccessHandler每一个消息被发送到客户端的时候handler被调用。

接下来的代码展示了每一个handler方法的签名:


SuccessHandler的参数是CometMessage类的一个实例。下面的代码显示了类和它的JSON格式:


发送一条消息

在这个聊天的应用程序中,我已经包含了一个能使用AJAX的WCF web 服务来扮演发送消息功能的结束点。下面的代码显示了点击发送消息按钮的客户端事件的处理器:


这段代码构建了一个由asp.net Web Service framework创建的 ChatService客户端对象的实例。然后仅仅调用了SendMessage方法,通过传递客户端的私有令牌和消息。

SendMessage代码携带参数以及写了一条消息给所有的客户端。下面的代码展示了功能:


这个方法从私有令牌中查找CometClient,并且创建了一个被用来作为消息内容的ChatMessage的对象。这里的消息内容通过CometStateMessager的实例的SendMessage方法被发送到每一个连接着的客户端。它将处罚任何连接着的客户端来回调包含在chat.aspx页面里的SuccessHandler方法。它将信息写到页面的聊天区域。


使用这段代码

解决方案中的网站执行的时候不需要改变任何的配置,仅仅连接一些客户端到应用程序中。并且聊天信息应该被实时发送。

使用这个API将使你能在你的AJAX程序中使用一个Comet风格的方案。使用WCF能使你发送消息到服务器,这些都已经为你自动包装了。然后仅仅只是在一个Comet通道中回调来连接到客户端。



原文发布时间为:2011-09-02


本文来自云栖社区合作伙伴CSDN博客,了解相关信息可以关注CSDN博客。

目录
相关文章
|
17天前
|
前端开发 JavaScript 关系型数据库
从前端到后端:构建现代化Web应用的技术探索
在当今互联网时代,Web应用的开发已成为了各行各业不可或缺的一部分。从前端到后端,这篇文章将带你深入探索如何构建现代化的Web应用。我们将介绍多种技术,包括前端开发、后端开发以及各种编程语言(如Java、Python、C、PHP、Go)和数据库,帮助你了解如何利用这些技术构建出高效、安全和可扩展的Web应用。
|
1月前
|
监控 Serverless 测试技术
Serverless 应用引擎常见问题之做的web服务计费如何解决
Serverless 应用引擎(Serverless Application Engine, SAE)是一种完全托管的应用平台,它允许开发者无需管理服务器即可构建和部署应用。以下是Serverless 应用引擎使用过程中的一些常见问题及其答案的汇总:
407 3
|
1月前
|
前端开发 数据库 UED
构建高性能Web应用的关键技术
本文将介绍构建高性能Web应用的关键技术,包括前端优化、后端优化、数据库优化等方面。通过深入讨论各项技术的原理和实践方法,帮助开发者们提升Web应用的响应速度和用户体验。
|
1天前
|
存储 中间件 Go
探索Gin框架:快速构建高性能的Golang Web应用
探索Gin框架:快速构建高性能的Golang Web应用
|
1天前
|
前端开发 JavaScript Java
前端与后端:构建现代Web应用的双翼
前端与后端:构建现代Web应用的双翼
|
1天前
|
安全 前端开发 JavaScript
在Python Web开发过程中:Web框架相关,如何在Web应用中防止CSRF攻击?
在Python Web开发中防范CSRF攻击的关键措施包括:验证HTTP Referer字段、使用CSRF token、自定义HTTP头验证、利用Web框架的防护机制(如Django的`{% csrf_token %}`)、Ajax请求时添加token、设置安全会话cookie及教育用户提高安全意识。定期进行安全审计和测试以应对新威胁。组合运用这些方法能有效提升应用安全性。
3 0
|
10天前
|
缓存 负载均衡 数据库
优化后端性能:提升Web应用响应速度的关键策略
在当今数字化时代,Web应用的性能对于用户体验至关重要。本文探讨了如何通过优化后端架构和技术手段,提升Web应用的响应速度。从数据库优化、缓存机制到异步处理等多个方面进行了深入分析,并提出了一系列实用的优化策略,以帮助开发者更好地应对日益增长的用户访问量和复杂的业务需求。
15 1
|
10天前
|
缓存 监控 数据库
Flask性能优化:打造高性能Web应用
【4月更文挑战第16天】本文介绍了提升Flask应用性能的七大策略:优化代码逻辑,减少数据库查询,使用WSGI服务器(如Gunicorn、uWSGI),启用缓存(如Flask-Caching),优化数据库操作,采用异步处理与并发(如Celery、Sanic),以及持续监控与调优。通过这些手段,开发者能有效优化Flask应用,适应大型或高并发场景,打造高性能的Web服务。
|
11天前
|
数据库 开发者 Python
Python中使用Flask构建简单Web应用的例子
【4月更文挑战第15天】Flask是一个轻量级的Python Web框架,它允许开发者快速搭建Web应用,同时保持代码的简洁和清晰。下面,我们将通过一个简单的例子来展示如何在Python中使用Flask创建一个基本的Web应用。
|
15天前
|
JavaScript 前端开发 API
Vue.js:构建高效且灵活的Web应用的利器
Vue.js:构建高效且灵活的Web应用的利器