一、客户端技术的考虑
导言
说到实时互动,我们直接能够想到的是聊天室或者Web IM,虽然因为xxx的原因,国内大多数文字聊天室都已经关闭,而视频聊天室,大多都是一帮xxx的美女在那边跳舞,越来越少的人在关注这个领域。
可是企业应用的角度恰恰相反,Web客服、内部IM、实时教学等业务的兴起,也会为这个领域的繁荣注入了强心剂,对于交互日益复杂的今日,我们又将以怎样的视角来设计我们的架构,又应该从哪些技术来考虑,更加应该考虑如何平衡技术与业务的关系,这是我撰写本文的初衷。
言归正传,还是从最简单的地方入手,我们来写一个聊天室,简单无比的聊天室。如果您从事过多年的Web开发,相信对此不会陌生。从最早的CGI到asp,再到现在的百花齐放,跟随着互联网这十年的发展,对于实时互动也经历了多个阶段。
抛开早期的CGI编写聊天室(大多是使用Perl,在98、99年左右),因为对于我们大多人来说已经有些陌生。我们就说用asp吧,编写简单的聊天室几乎是web编程的一门必修课,实现原理简单的出奇:
1. 建立一个frameset的html页面,分为三栏,主要区域显示聊天内容,右边为用户列表,下方为发言区,如下图所示:
2. 在线列表和聊天内容的页面在Header部分分别加入下面这样的Meta
<meta http-equiv="refresh" content="2;url=http://www.yoursite.com/newpage.htm" />
3. 将所有用户发言和用户列表存储在Application变量中,通过定期刷新获取用户聊天内容和在线用户列表
4. 在此基础上扩展私聊、表情和管理的功能
5. ……
用这样的篇幅来形容一个聊天室的基本原理,我想已经足够了,当中几乎不用JavaScript,更加别说Ajax了,虽然xmlhttp被微软早在IE5 Beta的时候就引入,但是并没有得到太多人的关注,要实现所谓的“无刷新”,大抵还是通过隐藏Iframe的方式来实现的,在那个年代,在聊天室听到页面刷新发出的声音也不足为怪。
为了更好的用户体验,采用CGI编写聊天室的高手们则是使用了Server Push技术,也就是显示聊天内容的页面和服务器始终保持连接,一旦有用户新的发言,立即被推送到浏览器,也就做到了基本上的实时。
随着Ajax的兴起,对于这样的应用,我们拥有了更多的方案选择空间,通过XMLHTTP队服务器发起一个请求,然后将获取的数据通过JavaScript的方式渲染到浏览器,再也没有烦人的刷新声音,又不需要用到CGI这样的高深技术,相关的应用的繁荣也就情理之中了。
通过Ajax后台请求服务器,然后通过设置一定的Interval,这是当前大多实时互动业务的基本实现,对于大多业务而言,也能够满足要求了。但是如果面对更加严苛的场景呢,我们的技术是通过刷新来实现模拟“实时”,但是真正面临要求实时的场景,如工业控制的监控、实时演示、实时报价、体育直播等,这是我们将会面临这样的问题:
l 对于状态的刷新频率,我们是通过setInterval或者setTimeout来实现的,从某种程度来说,我们的时间设置频率就是实时的延迟时间
l 如果设置为2秒,那么意味着我们存在两秒的延迟,我们可以把这个时间调整到500毫秒,理论上能够更加接近实际业务的要求,但与此同时也带来另外一个问题
l 频繁的刷新会导致服务器资源的浪费和无谓的网络带宽
l 在小规模用户的场景下,这些资源的空耗可以忽略不计,但是在大规模用户(如超过2万在线用户),服务器资源和网络带宽就变成不可忽视的课题
谈到这里,我们也清楚了设计一个大规模实时互动系统需要的一些关键目标:
1. 从客户端来说保证“实时”,也就是需要服务器和浏览器建立起实时的通信,在服务端数据变化的时候,能够第一时间推送到客户端,也就是说我们需要一个“服务器推”的技术。
2. 提高单一服务器的处理能力,通过一定的技术保证不会因为“实时”的要求而导致服务器效率的低下。
3. 设计一个可伸缩的服务器网络架构,以保证在单一机器性能到达峰值的情况下,可以通过增加服务器来实现服务能力的提升,而非只能够通过提高硬件配置
4.