Long polling

这两天在公司的项目里用了 Long polling,了解了它的实现原理,其实不像它的名字那么玄乎,只是 Ajax 和 HTTP 的类似小妙招的办法。

先解释一下 Long polling 是什么:

首先得说到传统的 Polling,Polling 是 Ajax 隔一段时间去抓取服务器上的数据,检查数据是否更新,但这样有很大问题,首先是每次请求会实用一个  HTTP request,对应的服务器就得建一个新的线程来处理这个 HTTP request,消耗网络流量、服务器资源不说,绝大多数情况下,数据短时间内是不会更新的,也就是说绝大多数的 Ajax 请求都只能无功而返。

而 Long polling 就是用来解决这个问题的。


它的核心是:
1. 做一个超时非常长的 Ajax 请求,并且在错误捕获代码里不断执行自己。2. CGI 部分接收到请求后在限定的时间内(Ajax 超时时间内)每隔一段时间(例如一秒)对数据库进行查询,可以使用 sleep 类似的方法。
3. 如果有新的数据则返回,如果即将到 Ajax 超时的时间则返回一个错误值,比如 404,这样那个非常长的 Ajax 请求会再发一个过来,继续查询。

这个办法的最大价值是有效减少了 HTTP 请求数,对服务器而言就不用开启新的线程去处理它,旧的线程如果不是因为超时,则只会在数据已经更新的情况下返回数据。可以节约大量资源,而且实时性更高。

目前,人人网的消息提示、Web 版阿里旺旺、新浪微博的新微博提示应该都是使用这种方法做的。

但这个办法对开发有一定困扰,Django 内置的 Web service 是单线程的,一个非常长的 Ajax 请求会占用那唯一一个线程,导致别的请求无法响应。

所以最好做好两套配置,一套用于产品环境的多线程环境,一个用于开发的单线程环境。

我依然对那位在现有架构下想出这种办法的人表示钦佩。

这儿有范例代码,简单又实用:http://stackoverflow.com/questions/333664/simple-long-polling-example-code

Posted by K*K Fri, 08 Jul 2011 17:49:20 +0800


JavaScript 加密器

 给软件写个彩蛋,但是又不想随便被别人看见,于是乎给脚本加下密就成了必须的了,不是为了 Property software,而是来个 Easter egg 来取乐 :-)

找来找去,找到一个 JavaScript Compiler 还不错,经过测试可以在 Firefox 和 Safari 上正常使用(IE 就不考虑了,手头也没机器测试),普通的 Encrypt 工具可能可以支持 Safari,但是对 Firefox 的支持可真的是非常一般。

地址在:http://www.virtualpromote.com/tools/javascript-encrypt/

比如经典的 Hello World:

alert("Hello World");

被加密后就成了:

var enkripsi="cngpv'0:'00Jgnnm'02Umpnf'00'0;'1@"; teks=""; teksasli="";var panjang;panjang=enkripsi.length;for (i=0;i<panjang;i++){ teks+=String.fromCharCode(enkripsi.charCodeAt(i)^2) }teksasli=unescape(teks);document.write(teksasli);

看不懂了吧? ;-)

不过使用 JavaScript Compiler 有限制,生成的代码必须以单独的文件存放,而且文件还得写上 JavaScript 的标记段,因为其实它的原理是将加密的内容,解密后直接插入 DOM 树里形成的,如果不这样做,将会在浏览器窗口中直接看到解密后的 JavaScript  代码,从这种意义上说,它就不仅仅是 JavaScript 的 Compiler 了,HTML、CSS 一类也可以用它加密。

而且为了让加密后的代码能够更加容易地调用,我们最好还能够写成 Function 的模式。

这里是可供调用的完整的代码:

<script type="text/javascript">
function helloworld() {
    alert("Hello World");
}
</script>

加密后的代码就成了:

var enkripsi="'1Aqapkrv'02v{rg'1F'00vgzv-hctcqapkrv'00'1G'2Cdwlavkml'02jgnnmumpnf'0:'0;'02'5@'2C'02'02'02'02cngpv'0:'00Jgnnm'02Umpnf'00'0;'1@'2C'5F'2C'1A-qapkrv'1G"; teks=""; teksasli="";var panjang;panjang=enkripsi.length;for (i=0;i<panjang;i++){ teks+=String.fromCharCode(enkripsi.charCodeAt(i)^2) }teksasli=unescape(teks);document.write(teksasli);

把它单独存成一个文件(比如 foo.js),然后引用它:

<script type="text/javascript" src="/js/foo.js"></script>

以后,只要在程序中调用 helloworld 函数就可以显示 Hello World 了。 :-)

Posted by K*K Tue, 16 Dec 2008 23:02:49 +0800