HTML5 以前,HTML 还不支持 WebSocket ,当时如果要进行实时的内容更新,要么使用 Ajax轮询(Polling) 或者使用 Comet 技术。
Non-Websocket
Ajax 轮询
在 2005 年, Jesse James Garrett 提出 Ajax (Asynchronous JavaScript and XML, 异步 Javascript 和 XML)。具体请看 Ajax: A New Approach to Web Applications 。并且从那时开始流行使用 Ajax 进行异步处理客户端请求。【关于异步处理请求的历史,可以看 http://en.wikipedia.org/wiki/Ajax_(programming) 中相关的介绍】。
XMLHttpRequest 在后台对服务器发起 request ,当收到 response 的时候,进行 DOM 操作,从而达到部分更新页面内容的目的(而不需要整个页面刷新)。
Ajax 轮询 可以做到接近实时的更新内容,但是因为是由客户端发起请求,即服务器处于被动的状态,这种“实时”存在缺陷:
(1) 伪实时。服务器有更新的时候,只有客户端发起请求,服务器才能将更新返回到客户端。
(2) 数据更新量少的时候,容易造成浪费带宽、流量。
(3) 请求频率难以把握。太快会对服务器造成过大的压力,而太慢又不够“实时”,权衡频率需要考虑的因素很多。
Comet 技术
Comet 是指不需要客户端浏览器安装任何插件,仅靠浏览器和服务器之间的长 HTTP 连接实现服务器向客户端通信(服务器推)的技术。
Comet 有两种方式: Ajax长轮询 和 iframe with htmlfile stream
iframe with htmlfile streaming
这种技术,暂时没使用过。基本原理是使用 iframe 标签在 html 中插入一个隐藏的帧,向服务器建立长连接,服务器不断地向 iframe 输入数据。
WebSocket
WebSocket 是 HTML5 的新功能,它是一种 TCP 协议。当客户端和服务器完成握手,建立连接之后,ws 就如普通 socket 一样,在两者之间进行通信。
理解了基本通信原理,就可以进行编程了。
前面已说,WS 是一种 TCP 协议,所以是语言无关的,用任何语言都可以实现服务器端的编程。我选择了 Python,使用 _flask: http://flask.pocoo.org/ 作为框架,以 _Gevent: http://www.gevent.org/ 和 _gevent-websocket: https://pypi.python.org/pypi/gevent-websocket/ 做 HttpServer。
实时更新基本的实现思路:
- 客户端发起 ws 连接请求
- 服务器响应,并且把 ws 加入到 observer 数组中。
- 当某一 ws 向服务器发送信息时,服务器遍历 observers 数组向每一个元素发送信息。
- ws 断开连接时,从 observer 中剔除。
具体实现代码:
~接下来可以实现 HTML5 的桌面直播了。