【心得】8年漫长的Web Socket之路

      8年前的今天,本人还是刚踏入互联网不久的小菜鸟。记得那还是一个IE5的时代,Win98的经典风格和亲切的蓝屏画面仍旧是记忆犹新。不过抱着对这未知世界的好奇,很快学会了新手最爱的开门语言——VB和HTML。顺着VB熟悉的手感,不经意间过度到了VBScript。在那个IE统揽天下的时候,VBScript仍然是流行的网页脚本语言,而JavaScript类似Java那陌生的风格反倒让我倍感别扭。

 

      那时的网站还是比较简单的,表格布局的前台,配合ASP和Access制作的后台,就是一个典型的网站。网页脚本也只是简单的验证验证表单,或者就是一些网页特效,例如图片跟随鼠标之类的。不过和大家不一样,我做网页纯粹是为了写脚本。起源很简单,当时打算用VB做一个扫雷的小游戏。游戏代码虽然很简单,但是要绘制管理游戏界面确有些麻烦。仔细一想,扫雷的主界面不就是一个NxN的表格吗,若是换成VBScript只需几行就可以搞定。不仅仅生成简单,而且想要改变表格尺寸,边框大小等等风格,只需修改几个字符就可以。这是第一次体验到了网页脚本的强大之处——用简单的方法制作复杂的界面,因此可以把更多的精力花在内容上,而不是实现上。

 

      随着对脚本的熟悉,打算做一个可以互动的东西,而不是简单的格子小游戏。此前在网上见到过ASP版本的在线聊天室,虽然做工不怎么样,但是羡慕这创意,希望自己也能做一个更完美的。因为这个聊天室是用ASP做的,显然它受到了种种的制约。他的原理其实很简单,每隔10秒钟自我刷新下,给人一种不安定的感觉,而且消息要么10秒钟不来,一来就是一堆,没有一种即时的感受。当时限制当时的技术,我也想不出更好的方法,直到03年7月的一天。。。

      Winsock的到来让我倍感兴奋。虽然VB使用已大半年,但此前的所有东西都是单机的,不于外界有任何联系。而现在可以把网络也当成程序的一部分来使用了。网络程序每个都是让人兴奋的,帖子刷新器,端口扫描器,简易的多聊天室,UDP炸弹(在QQ2003的版本可以把好友电脑卡死住)。。。在一阵狂热中学习了IP,TCP,端口,路由。。。网络的基本原理之后,又渐渐的开始考虑起此前的那个问题。

 

      因为ASP也是基于HTTP协议的,请求它立即回应,如果要让聊天室保证消息的即时性,那么网页必须不断的去访问它。如果人一多,服务器当然是经受不住的。而用VB制作的多人聊天室却是如此的简单,一个winsock做服务器,其他的最为客户端去连接,仅仅几段代码就可以搞定。于是我产生了个破天荒的想法:让vbscript创建一个Winsock,跟我的服务器通信!

 

      这个想法很是有意义。一旦成功的话,页面再也不用刷新了,只需脚本在后台传递数据,收到数据后也是通过脚本把消息写进信息框的div里(那个时候还不知道可以创建DOM的概念,但是知道可以设置innerHTML修改已有的内容)。我满怀信心的开始尝试,既然vb里面可以把winsock当控件拖出来用,网页里面肯定也可以用<object>标签来产生winsock,或者是创建ActiveX对象。但结果很是遗憾,试了各种方法,搜遍了google上的网站,也没能把winsock在网页里使用,或许这个想法太天真了点。尝试了几个星期后,打算放弃,不是放弃这个想法,而是用winsock的方法。

 

      经过一番研究,决定用曲线救国的办法:模拟一个winsock。winsock的数据传输都是在后台进行的,用户感觉不到。而在网页里通过刷新主页面肯定是不可行了;但我们可以不刷新主页面,只刷新页面里的框架,并且把框架做的足够小,甚至是隐藏掉,而框架和主页面是可以通过脚本相互调用的,这样不就是不用winsock也可以实现即时互动了?

      我用vb制作了一个的简易http服务器,绑定在8080端口上;客户端Web通过vbscript,让页面里的框架访问127.0.0.1:8080/+聊天参数;服务器程序果然收到了HTTP头部信息,以及后面的聊天信息,于是回传<script language=vbscript>window.parent.callback "Hello"</script>,记不得当时是怎样代码了,反正就是调用框架父页面的一个函数,这时页面里面的Msgbox框果然跳出了Hello。

 

      因为vb是基于消息事件的,所以winsock在收到数据后不必立即回复,可以在定时器里缓存一下,等数据积累多了或者一定时间后再回复。这一点与传统的HTTP协议在本质上就有了天壤之别,也正是这点使得这个即时聊天室得以实现。

 

      经过一番整理,聊天室有了如下的事件机制:

      1.脚本修改框架路径 --> 2.数据通过路径值传递到我的服务器 --> 3.服务器处理数据 --> 4.服务器定时器分发数据 --> 5.客户端脚本收到回调数据 --> 6.脚本分析并显示数据 --> 1。。。。。

 

      页面与服务器就是这样一轮一轮的消息循环着。消息可以在很短的时间里同步到所有的用户上,几乎实现了即时。

 

      在接着的研究中,发现使用框架传递数据是完全多余的,事实上只需改变一个SCRIPT元素的SRC值也可以达到此效果。而服务器回传的数据可以简单的多,只需X "....."的格式就可以了,X当然就是页面里的回调函数名。

 

      经过界面上的包装,这个聊天室也算是大功告成了。Socket我们无法实现它,但可以模拟它。当然,缺点也很是明显,页面时不时的加载一个脚本文件,鼠标也时不时的闪烁成沙漏光标,浏览器的状态也总是表现成加载中,用户还是能够感觉到数据的传输。当然,我也尽了最大努力去尝试改进过。

 

      ----------

      06年的一天,在上网时不经意间发现不少网站都没了页面切换的现象,比如163的邮箱,都是单一页面的模式了。那时也有好久没有研究Web方面的事了。打开网页源码一看,原来用到了一个xmlhttp的控件,难得这就是传说中的winsock吗?立即开始测试。不过结果还是令人失望,虽然使用它用户已经完全感觉不到数据的传输了,但他有个致命的缺点:只能访问同一域名同一端口的URL,这不是违背了当初的资源服务和数据服务的分离吗?这仍然不是我想要的,尽管现在绝大多数的网站都是用此插件。

 

      ----------

      07年,在学习Flash的时发现他早已支持Socket。既然Flash已是绝大多数电脑都有的控件,还有什么理由不用他呢?我写了一个只有基本功能的Socket,其swf只有300多字节,供js调用,js再封装成一个socket类,可以连接,可以发送,可以断开。。。此时,一个的socket终于诞生了,然而经过一番使用后才发现,他并非真正的socket——他依然受到沙箱模型的限制,想访问外域的主机还必须有跨域服务。不过无论如何,当年的愿望还是实现了。

 

      ----------

      09年的时候AS3.0已是如火如荼了。socket不仅仅是发送文本,二进制的数据流也可以了。此时的Flash已远不是当初那个播放矢量动画的控件了。类似Java的一个个功能强大的包,高效的计算速度,复杂的图像处理,几乎可以胜任一切的RIA。类似当初的即时聊天室用Flash制作的层出不穷,效果体验也甚好。基于Web单独的Socket似乎也显得没有什么必要了。

 

      ----------

      今天,把Opera升级到了11版。在更新内容里面发现有一条:支持HTML5的WebSocket。

 

      此前,能支持WebSocket的唯独Webkit内核的浏览器,如今又多了一个。HTML5日渐规范,越来越多有用的功能和特征被加入到了HTML5当中,似乎又要掀起一波纯Web的热潮。当HTML5能被所有的浏览器完善的那天,我也许又开始用脚本写着Socket,制作更多精彩的互动和游戏。不过当初只是纯粹为了好玩而设计的消息模型,如今却发展成了Web的主流,这点是我不曾想到的。。。(2011/2/14)

posted @ 2011-03-11 15:18  EtherDream  阅读(4938)  评论(14编辑  收藏  举报