[理论]5W2H分析法

mikel阅读(1079)

 5W2H分析法又叫七何分析法。简单、方便,易于理解、使用,富有启发意义,广泛用于企业管理和技术活动,对于决策和执行性的活动措施也非常有帮助,也有助于弥补考虑问题的疏漏。
  
  (1) WHY——为什么?为什么要这么做?理由何在?原因是什么?
  (2) WHAT——是什么?目的是什么?做什么工作?
  (3) Where——何处?在哪里做?从哪里入手?
  (4) WHEN——何时?什么时间完成?什么时机最适宜?
  (5) WHO——谁?由谁来承担?谁来完成?谁负责?
  (6) HOW——怎么做?如何提高效率?如何实施?方法怎样?
  (7) HOW MUCH——多少?做到什么程度?数量如何?质量水平如何?费用产出如何?
  
    1) WHY 为什么?为什么会有网站策划,为什么要做网站策划。这里先提一下产品策划(或产品经理),互联网本身有很多产品,比如:Live在线;Delicous;Flickr;Imop;inout;再近一些,比如蓝色的桌面城市,数码频道,Page。这些产品本身一开始被定义出来的时候并不是体现在网站上,而是在整体的规划和对市场的把控上。而策划人员在接到产品的时候,需要把产品经理的产品来表现到网站上,而最终达到盈利的目地。为什么有网站策划,实际上是策划产品在页面上的体现。
  
    2) WHAT 是什么?策划人员在拿到产品的方案时,首先要明白这个产品到底是什么。很多人可能会一拿到方案就开始做,这个应该是错误的。余世维举了个例子,拿出一张纸,对所有人说,把你们面前的纸给撕了。。话没说完,有人开始撕,横着、竖着,什么样的都有。这个时候又说话了:请把你们的纸从下往上,45度的撕成两半。这个例子简单,说明了人和人的理解会有不同,不同的人有不同的想法,至于方案就更不能这样。积极的沟通和交流,是策划人员和产品人员这个时候要做的重要一步。
  
    3) Where 从哪里着手? 沟通到了深入的一步的时候,应该把握产品的重点方向是什么,何时开始或准备盈利。(当然影响这些的因素有很多,比如渠道等。)了解这些东西,可以开始着手重点的表现层的东西,也就是说可以开始网站的流程上的思考了。这个时候大都是这么开始,从个人的经验上来看,人的因素占了很多,所以进行到Where的时候要了解具体哪个人负责哪件事,做好下一步的沟通准备。
  
    4) WHEN 何时?什么时间完成?什么时机最适宜? 我想针对于网站策划,什么时候完成似乎变得不重要了。什么时候是死线往往成了最重要的时间。我列出来一些网站策划要考虑的几个关健时间:何时开始、何时进行原型设计,何时进行讨论,何时完成设计稿,何时开始制作,何时开始开发,何时开始联调,何时进行测试,何时进行发布。
  
    5) WHO 谁? 其实这个部分从一开始就应该考虑到,涉及网站的相关有多少人,每个人都是什么类型。有的设计师比较有经验,不用讲太多就能明白你想要的效果;有的不喜欢产品,确能很按时的完成任务;有的产品经理不是太懂,确能对产品付起责任。每个人都是不同,针对不同的人要多沟通,多了解对方总有好处。看一下合作成功的两个公司的领导或相处很好的朋友,总能笑西西的一起吃饭喝酒。
  
    6) HOW 如何去做? 网站策划不是口头表达,总有一定的规律性和可操作的流程。写好一份完整的网站策划书实在不简单。我想谈的有几个关健点。一是简述产品的概念和要达到的目的,让相关人士进行初步了解;二、规定好时间段,特别是Deadline,把项目的执行力体现在时间段上;三、规划好网站的布局,从二级开始到一级;从流程到整体,让项目人员完全了解网站的概况及操作;四、描述产品定位给网站所要求的风格,这个时候可以给设计师一些参考的元素,设计师对理性的东西往往不是太重视,给他们感性的元素会很快的上手网站设计;五、网站的内容是什么,要确定下来,此时的定义对于网站上线后的测试和修改都相当重要,如果一个产品上线后还改来改去,用户不知道会烦到什么程度。
  
    7) HOW MUCH 在这里我想谈一下质量控制。有次工作中上线后出现了一个错别字,查到最后,原来是产品经理打错了一个字。追其过程,策划人员拿到文案,然后 Copy到策划书里,然后交于设计师,设计师再Copy,再交于制作人员,再交于开发,再交于测试,再交于上传。完了,整个过程没有一个人看到这个错别字。日本人在这里做的非常好,由西方提出来的质量管理他们延伸到全面质量管理”Total Quality Management”. 我并不在于夸日本人,而是全面质量管理确实有利于网站策划人员,用TQM的思想来把控网站的质量问题。如果是这样,那么测试人员是不是要下岗了?
  
    提出疑问于发现问题和解决问题是极其重要的。创造力高的人,都具有善于提问题的能力,众所周知,提出一个好的问题,就意味着问题解决了一半。提问题的技巧高,可以发挥人的想象力。相反,有些问题提出来,反而挫伤我们的想象力。发明者在设计新产品时,常常提出:为什么(Why);做什么(What);何人做(Who);何时(When);何地(Where);如何(How);多少(How much)。这就构成了5W2H法的总框架。如果提问题中常有“假如……”、“如果……”、“是否……”这样的虚构,就是一种设问,设问需要更高的想象力。

[UI]用户期望的满足、超越和拒绝

mikel阅读(682)

对于需求和期望,我是这么理解:用户期望是需求的表现层,期望是用户对需求满足方式的一种假设。
举一个例子:
朋友给张三推荐一首《海阔天空》,张三于通过搜索引擎到达某个网站,他的期望是:找到下载的链接>下载>离开网站
满足期望
网站如果提供下载,应该尽可能地帮助张三在最短的时间内完成这个任务。张三在完成这个下载之后,下载下来的歌曲质量恰好是他想要的,下载速度也很满意。张三的期望得到满足,网站能获得的:
1 如果张三下次还有想听的歌,很可能不通过搜索引擎直接访问到网站,网站就有机会将其转化成长久用户。
2 张三可能会介绍他的朋友来这个网站。
超越期望
张三是期望到该网站能下载《海阔天空》,但他的真正需求是这样吗?或许不是,他也许只是想听一下这首歌,只不过他认为他应该下载下来满足他听的需求。
如果该网站告诉张三,我们这不但可以下载,还可以在这里在线听,而且速度不卡。张三很满意,算了,我就不下载了。
再进一步,网站又告诉张三,beyond的歌还有《大地》、《光辉岁月》…,现在流行的歌有《青花瓷》、《老人与海》…张三感觉发现了新大陆,于是把该网站存进收藏夹,并且经常来这听歌。
……
尽管网站可以下载《海阔天空》,但我们发现,网站并没有满足张三的期望,但是解决了他的需求,因为网站给张三的解决方案要优于他的假设。
拒绝期望
如果该网站是一个音乐社区,主要提供音乐信息的交流和分享,提供试听但不允许下载。网站应该让张三在最短的时间内知道:这里不能下载,但可以…
如果张三的需求底线就是下载到本地,那OK,张三暂时就不是你的目标用户,礼貌地将其送出门。
很多网站都想方设法要把用户留住,不惜代价“迷惑”、“欺骗”用户,填写更多的资料,做更多地点击,到最后用户一边骂娘一边离开,现实中处处见到这样的“流氓拉客”方式。
好的设计应该懂得拒绝!
期望的变化
起初大家上网找音乐都是为了下载,但随着网速的加快,版权问题等因素,当第一个在线听歌的网站出来以后,慢慢地很多网站都提供在线听,人们以后再到音乐网站,期望也会发生改变。
当在线试听成为一个普遍的、基本的需求之后,如果有一个网站可以将在线听歌同步到手机、MP3等等各种终端,那又超越了用户的期望。
转载请注明出自UCDChina.com,谢谢。

[Java]Liferay Portal 5.0 发布,Sun加入其社区

mikel阅读(730)

在上月的JavaOne大会上,Liferay公司发布了Liferay Portal产品5.0版。Liferay公司的新闻稿着重介绍了该门户产品的一些关键工具和应用:

Liferay Portal 5.0囊括了当今企业需要的核心协同工具,包括:

  • 博客,留言板,Wiki
  • 动态标签系统,以此完成用户驱动分类
  • 基于 AJAX的邮件客户端,用户可以直接通过门户发送Email
  • 共享的日历,聊天和投票功能
  • 可通过Portlet直接发布内容到MySpace和Facebook
  • 在部署门户时,可以直接集成iGoogle gadget的功能

Liferay的CTO Michael Young, 在InfoQ对该产品4.4版本发布的新闻报道中承诺,5.0版本将兼容JSR 286。有关规范将在月底完成,并包括了许多新的特性。Liferay的Jorge Ferrer 强调了其中的一些特性

  • Portlet之间的交互通信 (又名 IPC): 有两种新机制实现这个目标。第一种称为“共享描述参数”,允许portlet设置可供其它portlet读取的参数。这个简单的机制几乎能够满足所有的需 要,除非是特别复杂的通信需求。第二种方法基于事件,专为复杂的通信需求设计。这种方式的主要好处在于,它允许充分的非耦合沟通。portlet发起一个 事件,不用关心是否有其他portlet监听。
  • 资源服务: 这个特性非常有用,不仅可用于文件之类的二进制内容,还可以极大改善portlet对AJAX提供的支持。通过新的serveResource()方法,它能处理HTML片断、XML、JSON,以及其它客户端可以采用的AJAX应用
  • Portlet过滤器:在请求提交到portlet之前或之后,可以增加过滤器以执行代码。目前Apache Portals提供的解决方案已经可以做到,并成为了部分标准。这会使得portlet更易于使用,甚至有助于促进可重用过滤器的开发。

另外,Liferay公司宣布,Sun公司正式加入Liferay开源社区。Liferay的CEO Bryan Cheung 分享了他的兴奋之情

Sun加入Liferay开源社区, 对我们社区的实力和我们产出的软件质量是一种肯定。我们对于开放标准的承诺,意味着Liferay将会易于集成Sun家族的产品。非常高兴Sun的加入,我们会开发出伟大的软件来为社区服务。

更多Liferay的内容请查看公司网站http://www.liferay.com.

查看英文原文: Liferay Portal 5.0 Released, Sun Joins the Team

[Flex]JumpShip框架发布新版本

mikel阅读(801)

做为对开源Flex和ActionScript富因特网应用(RIA)最新的补充,Jumpship 3.1版在2008年5月21日发布了。InfoQ为跟上RIA开发框架的 步伐,做了很多努力,其中之一就是访问了JumpShip框架的作者Jamie Scanlon。Scanlon还是Web设计室(Web design house)JSJ Studios的主人。他说之所以要开发JumpShip,是因为开发者们都会面对的可用性问题。Scanlon回忆道:

如今的JumpShip框架,在一开始时只是我一个人的小打小闹。创建它的想法事实上是在我完成了一个超大项目之后产生的, 因为那时候我可以歇下来休整休整,看看刚刚完成的项目。完成的项目使用的是MVC (一种用于SOA的快速RIA构造器)。虽然最终的软件可以工作,但是代码对于我来说还真有些复杂。controller和view都得要几百行代码。调 试时,单是查找有问题的代码所花的时间就与改正错误代码的时间一样长。我知道马上又要开始一个规模差不多的新项目,所以我特别想找到个更好的方法。

那时,我发现了 Ruby on Rails。在框架中我想要的所有东西,Ruby on Rails都一应俱全,特别是它的简练是我最想要的。尽管也基于坚实的理论,但它追求的是能把任务完成就好,而不是像“四人帮”的设计模式那样“阳春白雪 ”。我希望ActionScript也有这些,所以我开始行动起来。

Scanlon解释道:

JumpShip的目标是:重视MVC的最佳实践,但稍稍偏重于“把任务完成就好”。JumpShip不害怕为了实用性而 对理论有所牺牲。JumpShip还努力坚持Ruby on Rails的“约定优先于配置(convention over configuration)”思想。JumpShip采用的方法是:在没有一个清晰的最优解决策略时,将“把任务完成就好”当作是最优方法。对于一个框 架来说,这并不是一件坏事。采用约定就意味着可以在最佳实践的选择上少花费时间,而将精力更多地放在编码上。

就JumpShip和其他AS3框架(如ARP、Cairngorm或PureMVC)有什么不同这个问题,Scanlon回答道:

JumpShip最独特的特性之一是其中内含了标准数据模型,可以自动进行查找、排序、数据的遍历和枚举。在prototype社区已有工作的基础上,JumpShip的数据模型提供了难以置信的功能强大的数据结构,它可以在整个框架中起作用。

JumpShip和其他MVC框架之间另一个主要区别在于JumpShip在生成对其他类的引用时有意不依赖于单例(Singleton)模式这种简单方式。

他回忆道:

最近我曾写过一件自己经历的事情。我用Cairngorm构建了一个视频播放器,想把它移植到另一个需要多个播放器实例的 应用程序中。可是做完后我遇到了问题,我意识到:因为使用了单例ModelLocator和Cairngorm的EventDispatcher类,所以 只要我单击任何一个播放器实例的播放按钮,面板上所有的播放器实例都会监听到单击播放按钮这个事件,大家同时开始播放。

我坚信,在大多数的框架中,使用单例模式时,考虑得都太少了。单例模式确实能够轻而易举解决无须对每个类的引用都进行存储的问题。这使得它们使用起来非常方便,但如果确实想要构建一个部件化、组件化的环境,单例模式用起来就不一定那么舒服了,有可能会坏事。

JumpShip还有一个与其他框架的不同之处是它使用了Rails网关,通过借助于Rails的RESTful Web服务为使用者提供了一个类库,这样就可以使用Rails的后台完成基本的CRUD(Create-Read-Update-Delete,创建-读 取-修改-删除)操作。至于JumpShip和Ruby on Rails的集成,Scanlon 解释道:

框架能有多简单、应该给开发带来多大方便,Ruby on Rails就是我心中的典范。基于使用Ruby on Rails的经验,我总想在框架中定义一个非常管用的数据模型。Rails中有一个ActiveRecord类,它是数据库表的抽象,既可以作基本的 CRUD操作,也可以完成查找、排序和数据遍历。当你开始将数据当成是数据库表的抽象时,你就会希望那些对数据进行的各类基本操作都是现成的。假定我的应 用程序中的数据都来自于数据库表中存储的各种值,我想让数据模型知道怎样对数据进行查找、排序、遍历和修改。 

我还想只搞一个数据模型,让它哪里都能工作。我不想在每个应用程序中都得定义值对象,即使明明知道这些值对象再也不会在别 处使用了。这种一个数据模型不仅仅在当前项目使用,而可以到处使用的概念,在ActionScript里还是个新想法。这样不仅节省了开发时间,而且还促 使程序员去思考像数据模型这样有助于应用程序和开发工作的一些事情。服务器给你什么形式的数据你就解析、存储什么样的数据,这并不是一个好方法。开发者们 常常会陷入这样的误区:把他们的数据模型构建的与他们得到的原始数据(如XML、JSON或原始对象)一模一样。从服务器传来的数据所含的结构很可能非常 适合于后台的业务逻辑。但是,做为前台的开发者,我们没有义务使那些传来的数据结构保持不变。我们可以而且也应该让数据为我们服务,而不是相反的去为数据 服务。

Scanlon对Rails网关也进行了评论,他回忆道:

在我开发JumpShip时,要使用rails后台,可是几乎没有任何资料讲解Rails如何与ActionScript 彼此互相通信。我经历了短暂的挫折,努力尝试来完成这个任务。但最后,并不像我想像的那么难,我只想说清楚我是怎么实现的。我想让Rails的开发者明白 他们开发的程序如何与Flash前台协同工作;我也想告诉Flash/Flex的开发者们不要太过专注于Flash Remoting和AMF,还要留意Web服务中其它更多的东西。

事实说明,并不是只有我一个人在走这条路。几个月以后,Adobe发表了一篇关于Flex和Rails协同工作的文章。不 管怎样,我一直坚持在改进JumpShip 的Rails网关,因为我觉得Rails网关是有价值的,它为Rails和ActionScript的协同工作提供了一种解决方案,不与Adobe的 Flex相关,它利用了我在做JumpShip数据模型时的一些成果。

我意识到拥有定义的数据模型的另一个好处:通过RESTful服务和XML就可以与Rails进行通信,可以将来自 Rails的所有数据转换成标准的JumpShip数据模型。因此,你可以创建一个叫做'users'的数据模型,并告诉JumpShip的Rails网 关在服务器上进行查询。网关自己知道在users数据库表中进行查询,并且会将XML查询结果转换成为JumpShip数据模型。这确实相当酷!你还可以 选一个JumpShip数据模型,告诉网关把它存储起来。网关知道怎样将数据模型转换成XML,并告诉Rails将其存储到数据库中。

尽管Rails网关对特定的一群ActionScript开发者有用,但我还是很惊喜的从要使用Flash做为前台的Rails开发者那里得到了大量积极反馈,他们认为 Rails网关很有用。

当InfoQ询问Scanlon在JumpShip框架中最想进行哪三大改进时,他回答道:

我会把文档创建工作列到第一位。我现在正在着手做这事。好的文档在帮助理解该框架的威力方面至关重要。但是太耗时间了,在文档方面,我自己也没有太好的习惯。

我也希望能加强这个框架的社区建设工作。我希望随着社区的扩充,有更多的人可以贡献出他们的想法和经验,这样框架就会不断成长和进步。

最后,我希望JumpShip的适用范围更广,它也能用在Flex框架中。JumpShip起初虽然是一个Flash框 架,因此我希望它在能继续为使用Flash的开发者提供帮助的同时,也能吸引越来越多的Flex开发者。尽管该框架在两种环境下都可以工作得很好,但是普 通Flex开发者会发现一些异于原来的新概念。我的目标是降低Flex开发者使用JumpShip的门槛,这样就会让他们像使用Flex相关的框架(如 Cairngorm)一样简单地使用JumpShip框架。

Scanlon指出JumpShip也非常适于创建可移植可复用的代码,比如小构件和组件,因为它更少的依赖于单例模式, 更不容易引起冲突。总之,Scanlon 把JumpShip 当作是一个实用的框架,该框架适合于那些希望迅速完成任务,而不过多考虑设计模式理论或者实现MVC最好方法的开发者们。

查看英文原文:ActionScript Framework JumpShip 3.1 Released with Extensive Ruby on Rails Support

[Flex]Flex地图制作

mikel阅读(966)

第一部:http://www.uncool.cn/blogs/read.php/166.htm  From UNCOOL.CN
     第二部:http://www.uncool.cn/blogs/read.php/167.htm  From UNCOOL.CN
     第三部:http://www.uncool.cn/blogs/read.php/169.htm  From UNCOOL.CN  
     第四部:http://www.uncool.cn/blogs/read.php/213.htm  From UNCOOL.CN  
     首先插播广告,这些教程是我UYang(www.uncool.cn/blogs)所写,地图API是来自cnflex.org站长SILVER所开发,如果你想更加牛B哄哄的开发出更牛B哄哄哄的程序,基础资料可以去cnflex.org论坛上寻找。


    从 前面的四篇,我们已经知道怎么把地图弄出来,怎么放大,缩小,移动,切换,加标签。一切可以应用到实例的基本功能我们都已经知道了,那么从这篇开始就是慢 慢的向实际应用靠拢,我的这个一系列教程最后的结果就是一个完整的实际应用程序,当然只是一个程序的最初DEMO并不包括服务器,你可以根据你的想法再进 行加工,加上服务器内容等,只不过那个就不属于FLEX的范畴了,你喜欢什么服务器语言就用哪种,所谓的八仙过海,各显神通。
      言归正 传,实际应用,我们第一部需要解决的是数据问题,我们需要显示那个点,或者在表格里点击,然后地图转向那个坐标点。一切的一切都是需要最初的数据,无论你 是后台哪种数据模式,最后的也是最重要的就是那个坐标点的信息,他到底在哪里?他的X轴,Y轴坐标在哪里?只有解决了这个,那么后面的程序才可以走下去。 所以这篇的DEMO属于参考DEMO,就是显示当前中心点的位置。很简单,先看下完成的DEMO
    
      
       按照前面4个教程,我需要的是你在FLEX面板上加上这么一句

<mx:VBox  right="20" y="347">      
    <mx:FormItem label="lng坐标:">
        <mx:TextInput text="" id="lng"  width="100"/>
    </mx:FormItem>
    <mx:FormItem label="lat坐标:">
        <mx:TextInput text="" id="lat"  width="100"/>
    </mx:FormItem>
  </mx:VBox>

       就是显示所谓的坐标点的界面,有两个id,一个是lng,一个是lat.是用来显示当前的lng坐标和lat坐标,比如定位地址就是靠lng坐标和lat坐标。
       某地 = (lng,lat);
      上海的:(121.45382,31.24717);
      北京的:(116.37819,39.92374);
      以上两个坐标点,都是我通过移动中心点而得到的数据,当然还是有点小偏差。
      那么我们如何在移动地图的时候,能够准确的得到中心点的坐标呢,其实这个更加简单了。在updateCenter()这个构造函数里,如果忘了,可以看以前教程的代码。在这个构造函数里加上下面这两句:

     lng.text = currentLngLat.x.toString() ;
     lat.text = currentLngLat.y.toString();

      新的完整的updateCenter()就变成:

private function updateCenter(event:MapUpdateCenterEvent):void{
         currentLngLat.x = event.lng;
         currentLngLat.y = event.lat;
         lng.text = currentLngLat.x.toString() ;
         lat.text = currentLngLat.y.toString();
       }

    这样这个第五部分的教程算是结束了,很简单,也很重要,所以就单独的成一个教程。下一部就是讲在点击表格里的数据后,地图直接转向那个坐标。由于这个系列教程写的时间过长,写的有点脱节,我会尽量在这个星期把这个教程完结掉。

[Flex]Mate Flex Framework

mikel阅读(772)

I’ve been testing Mate Flex framework.  It’s not intrusive, promotes building application components in a loosely-coupled way and implements design pattern Dependency Injection.  At this point Mate is in Alpha, but the way it was designed looks very encouraging, and people who are into MVC should definitely try it out.

The framework allows various ways for connecting model, view and controller, but I drew this diagram to illustrate its data flow that uses injectors.
Mate Framework Diagram

Is this diagram easy for understanding? I’d appreciate your feedback.

Thanks,
Yakov Fain

[问题]SQLServer2005与2000的Select Top语法不同的错误

mikel阅读(1130)

调试用的是SQLServer2005,写个语句如下:

Sel&#101;ct TOP (20)  id  FROM online o&#114;DER BY sdate

注意top的“( )”
帮助文档的说明如下:

语法
[
TOP (expression) [PERCENT]
[ WITH TIES ]
]
备注
在已分区视图中,不能将 TOP 与 Up&#100;ate 和 Del&#101;te 语句一起使用。
与 Ins&#101;rt、Up&#100;ate 或 Del&#101;te 一起使用的 TOP 表达式中被引用行将不按任何顺序排列。TOP n 随机返回 n 行。例如,下面的 Ins&#101;rt 语句包含 o&#114;DER BY 子句,但该子句并不影响由 Ins&#101;rt 语句直接引用的行。
参数
expression
指定返回行数的数值表达式。如果指定了 PERCENT,则 expression 将隐式转换为 float 值;否则,它将转换为 bigint。
在 Ins&#101;rt、Up&#100;ate 和 Del&#101;te 语句中,需要使用括号来分隔 TOP 中的 expression。为保证向后兼容性,支持在 Sel&#101;ct 使用不包含括号的 TOP expression,但不推荐这种用法。
如果查询包包含 o&#114;DER BY 子句,则将返回按 o&#114;DER BY 子句排序的前 expression 行或 expression% 的行。如果查询没有 o&#114;DER BY 子句,则行的顺序是随意的。
PERCENT
指示查询只返回结果集中前 expression % 的行。
WITH TIES
指定从基本结果集中返回额外的行,对于 o&#114;DER BY 列中指定的排序方式参数,这些额外的返回行的该参数值与 TOP n (PERCENT) 行中的最后一行的该参数值相同。只有在指定 o&#114;DER BY 子句之后,才能在 Sel&#101;ct 语句中指定 TOP ...WITH TIES。

SQL Server 2000 中的Top语法如下:

Sel&#101;ct TOP 20 id FROM online o&#114;DER BY sdate

一个语法错误可能让你郁闷不止一天啊,切记兼容性调试

[原创]ASP保持在线用户最新处理办法

mikel阅读(769)

由于需要准确控制在线人数,但是很难捕获用户关闭浏览器的事件来清理online表中的在线用户记录,造成在线人数不准,利用global.asa的session_onEnd处理,又不能及时清除,只有在timeout和session被清空时才触发,没办法只能在数据表online加入Inser,Update触发器清除定时30分钟后的记录来保持在线人session超时后有人上线或更新online的date时间后删除超时的online记录。
OnLine表结构

****** 对象:  Table [dbo].[online]    脚本日期: 07/02/2008 09:43:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Cr&#101;ate TABLE [dbo].[online](
[id] [int] IDENTITY(1,1) NOT NULL,
[compid] [int] NULL CONSTRAINT [DF_online_compid]  DEFAULT ((0)),
[employeeId] [int] NULL,
[sdate] [datetime] NULL CONSTRAINT [DF_online_sdate]  DEFAULT (getdate()),
[online] [int] NULL,
CONSTRAINT [PK_online] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

页面每次进入或刷新时判断sdate是否超过30分钟,如果超过更新sdate的时间为当前最新时间,这样保持在线时间一直是最新的时间,避免被删除

&#39;判断用户登录状态
if session("checklogin") then
if session("zjzxid")<>0 then
sessioncompid=session("zjzxid")
else
sessioncompid=session("compid")
end if
employee=session("employee")
set online=server.cr&#101;ateobject("adodb.recordset")
&#39;跟数据表中暂存的用户ID进行判断,其中sessioncompid中存储的是用户ID
online.open "sel&#101;ct id,compid,sdate from online wh&#101;re compid="&sessioncompid&" and employeeid="&employee,conn,1,1
if online.recordcount<>0 then
&#39;如果表中有该用户的话,就判断存储时间是否超出设置的超时时间
&#39;如果超时,那么将系统时间赋上,以保证当前的用户的状态
oldid=online("id")
if DATEDIFF("n",online("sdate"),now())>30 then
sql="up&#100;ate online set sdate=getdate() wh&#101;re id="&oldid
conn.execute sql
end if
else
&#39;如果表中没有该用户,则进行添加操作
sql="ins&#101;rt into online (compid) values ("&sessioncompid&")"
conn.execute sql
end if
online.close
set online=nothing
end if

触发器

Alt&#101;r TRIGGER [dbo].[clearOnline]
ON  [dbo].[online]
AFTER Ins&#101;rt,Up&#100;ate
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with Sel&#101;ct statements.
SET NOCOUNT ON;
-- Ins&#101;rt statements for trigger here
Del&#101;te online wh&#101;re datediff(minute,sdate,getdate())>30
END

[教程]Global.asa文件

mikel阅读(705)

  asp的application和session对象体现了其他asp内置对象所没有的特征–事件。每一个访客访问服务器时都会触发一个 onstart事件(第一个访客会同时触发application和session的onstart事件,但application先于 session),每个访客的会话结束时都会触发一个onend事件(最后一个访客会话结束时会同时触发application和session的 onend事件,但session先于application)。
  onstart和onend这两个事件一般应用在虚拟社区中统计在线人数、修改用户的在线离线状态等。要具体定义这两个事件,需要将代码写在 global.asa文件,并将该文件放在站点的根目录下(缺省是\inetpub\wwwroot\)。另外,application和session 对象规定了在onend事件里除了application对象外其他asp内置对象(response、request、server、 session…)一概不能使用。以下举一个虚拟社区统计在线人数的例子来说明如何使用这两个事件。
  文件说明:
  global.asa 位于d:\inetpub\wwwroot\目录下
  default.asp 位于d:\inetpub\wwwroot\目录下,虚拟社区登录页面
  login.asp 位于d:\inetpub\wwwroot\目录下,用于检测用户输入的用户名及密码
  index.asp 位于d:\inetpub\wwwroot\目录下,虚拟社区首页
  bbs.mdb 位于d:\inetpub\wwwroot\目录下,存储用户信息的数据库
  数据库(access)结构:
   ===bbs表===
  id 用户id,长整型
  name 用户名,文本型
  code 密码,文本型
  online 在线状态,是/否
 
  ===global.asa===
  <script language=”vbscript” runat=”server”>
  sub application_onstart
   application(“online”)=0
  end sub
  sub application_onend
  nd sub
  sub session_onstart
  end sub
  sub session_onend
   if session.contents(“pass”) then 判断是否为登录用户的session_onend
    application.lock
    application(“online”)=application(“online”)-1
    application.unlock
   end if
  end sub
  </script>
  ==============
  ===login.asp===
   ……密码验证,连接数据库,检测用户输入的用户名及密码是否正确
  if 密码验证通过 then
   session(“name”)=rs(“name”)
   session(“id”)=rs(“id”)
   session(“pass”)=true
  else
   rs.close
   conn.close
   response.write “密码错误!”
   response.end
  end if
  application.lock
  application(“online”)=application(“online”)+1
  conn.execute (“update bbs set online=1 where id=”&session(“id”))将用户的状态设为在线
  application.unlock
  rs.close
  conn.close
  response.redirect “index.asp” 初始化数据后跳转到社区首页
  ===========
  在本例中,用application(“online”)变量记录已经登录社区的在线人数,因为一旦有用户访问服务器而不管用户是否登录,都会产生onstart事件,所以不能在onstart事件里使applicaiton(“online”)加一。因为不管是否是登录用户的会话结束都会产生onend事件(假如有访客访问了服务器但并不登录社区,他的会话结束后也会产生onend事件),所以在session_onend事件里用了句if 语句来判断是否为已登录用户的onend事件,如果是才将在线人数减一。
  这只是一个统计在线人数的简单例子,对于一个完整的虚拟社区来说,仅仅统计有多少人在线是不够的,在本例中数据库里有个online字段是用来记录用户的在线状态,用户登录的时候,在login.asp里将online设为1,但用户离线时并没有将online设为0,要完善它,就要修改一下 session_onend事件,在该事件里将online设为0。
  ===global.sas===
  <script language=”vbscript” runat=”server”>
  sub application_onstart
   application(“online”)=0
   set application(“conn”)=server.createobject(“adodb.connection”)
   application(“db”)=server.mappath(“\bbs.mdb”) 此处最好使用绝对路径\bbs.mdb,下文有详细介绍
  end sub
  sub application_onend
   set application(“conn”)=nothing
  end sub
   sub session_onstart
  end sub
  sub session_onend
   if session.contents(“pass”) then 判断是否为登录用户的session_onend
     application(“con”).open =”driver={microsoft access driver (*.mdb)};dbq=”&application(“db”)
      application.lock
      application(“online”)=application(“online”)-1
      application(“con”).execute (“update friends set online=0 where id=”&session.contents(“id”))
      application.unlock
      application(“con”).close
   end if
  end sub
  </script>
  ==============
  至此,完整的代码已经完成了。因为在application和session的onend事件里不能使用server对象,所以要将数据库的连接及数据库在服务器上的物理地址(d:\inetpub\wwwroot\bbs.mdb)存储在application变量中,并在 application_onstart事件中预先处理。同理,在session_onend事件中不能用session(“pass”)来代替 session.contents(“pass”)(以下有详尽说明)。
  四、本文实例中值得引起注意的两点
  ⒈onend事件里的session.contents
  刚开始接触global.asa的朋友经常会将上面session_onend事件里的
  if session.contents(“pass”) then 写成
  if session(“pass”) then,
  这样的话系统不会提示错误,但是永远也不会执行then后面的内容,这是因为在onend事件里禁止使用session对象,但是可以用 session对象的集合来调用session变量。因为iis并没提示任何错误信息,所以笔者曾经在这上面浪费了很多时间。在此希望大家引以为鉴!
  ⒉application_onstart事件里用server.mappath获取数据库的物理地址时应使用绝对地址为了说明这个问题,大家可以做个实验:将上面application_onstart事件里的
  application(“db”)=server.mappath(“\bbs.mdb”)改为:
  application(“db”)=server.mappath(“bbs.mdb”)
然后在d:\inetpub\wwwroot\目录下建立一个test子目录,写一个temp.asp在test目录里。
  ====test.asp====
  <%response.write application(“db”)%>
  ================
再将temp.asp拷贝一份放在根目录下(d:\inetpub\wwwroot\)。用记事本打开global.asa,再打开两个浏览器,浏览器a输入地址http://localhost/temp.asp,按回车,将在浏览器上输出:
  d:\inetpub\wwwroot\bbs.mdb
然后,在记事本的窗口上点”文件”菜单,选”保存”(使global.asa的修改时间改变,从而使iis重启动所有服务),再在浏览器b输入地址http://localhost/test/temp.asp,按回车,在浏览器上输出的是:
  d:\inetpub\wwwroot\test\bbs.mdb
global.asa文件虽然是放在站点根目录下,但是如果在server.mappath中使用的是相对地址,而触发 application_onstart事件的用户第一次访问的页面又不是属于根目录的话,得到数据库的物理地址将不会是期望的结果,希望大家要特别小心。
文章整理:西部数码–专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

[SOA]SOA新一代语言Einstein

mikel阅读(885)

Einstein是一门针对分布式SOA复杂环境而设计的语言,它建立在以下主要原则基础之上:
* 分布式:Einstein被设计成允许(潜在的)每条指令可以在彼此分离的机器上执行。接下来由用户决定代码中实际期望的分布式和并发性的程度。
* 事件驱动:Einstein是一门基于流程的编程语言,各条指令通过消息进行通信。
* 并发性友好:在创建时,Einstein就考虑支持并发性;它使用一组经过验证的避免共享状态的技术(消息传递、只读元组等),具备运行时感知的线程安全性。
* 适当的复杂性:Einstein采用了一些包括资源和模型在内的简单技术来减少实现分布式系统的复杂性。
* 代替各种技术:Einstein 意在解决过去用来进行多系统集成的技术过多问题。目前,在构建一个资源交叉(cross-resource)系统时,我们常常依赖ESB、网格技术、分布式状态系统、协调技术(如BPEL)和工作流等技术。Einstein被设计成一种代替所有这些技术的工具。
Einstein的语言基于以下概念:
* 资源,与变量极为相似,但是一般是粗粒度的。资源使用URI来访问。资源可被描述成不稳定(可安全用于多线程访问)、局部(不打算用于多节点访问或串行化)和幂等(接收一条消息多次的效果和只接受其一次的效果相同)。
* 提供者,为任何资源接收、传送、执行、查询、路由或以某种方式处理消息提供了一致接口。一个提供者可被分成3个组件:ResourceProvider(扮演一个资源工厂),Resource(实现)和Facades(一个资源为其所提供功能暴露的简单粗粒度接口视图)。提供者被自动加载进Einstein注册中心,中心包含了与所有可用资源和提供者相关的信息。
* 消息是Einstein资源间交换数据的主要机制。一条消息的有效负荷包括一个数据对象而非一个语言对象,它允许多种数据格式(如XML、对象图、CSV文件等)与Einstein进行交互。
* 执行组,包括流程执行组(顺序执行、类似编配语言中的sequence)、元组执行组(并行执行,类似编配语言中的fork/join)、组合执行组(与元组类似,但是至少有一个分支结束时即结束)和映射执行组(以上组的结合)。
http://einstein.codecauldron.org/tw/tiki-index.php?page=DownloadPage