最近想在产品中加入即时通讯的功能.BS架构的程序.实现方式不外乎两大标准下的各种奇淫技巧.
这两大标准就是 HTML5 HTML4
为啥这两个呢..因为HTML5里面有websocket.这个彻底颠覆http请求的东西,使得请求不再是无状态的.
当然websocket目前支持不是很好.也没办法.看着好东西没法用.这是一种何种的煎熬....搞得我总是想在产品里面内嵌chromeFrame.然后强制给客户装上.哈哈...当然客户没准会和我拼命呢...
没办法,在现有的需求中基本上,实现思路只有一个了.也就是第一个让我头疼了一阵的关键词
"轮询"
这词看上去很高级的样子,其实就是写个ajax间隔一段时间不断向服务器请求内容.这活谁都干过.
然后我就想啊.如果用轮询实现,那也显得太低级了吧.怎么着.咱得弄个高级点的技巧显摆显摆..于是,查了一番资料,一个更加装逼的词语蹦到了偶的眼前
"长轮询"
看,变长了果然不一样了.这个词还伴随着一个英文
"comet"
其实原理很简单.以往的web请求,服务器处理请求后要立即返回,尽管超时的时间也能到达30秒这么多(并不是说用了comet才可以允许连接在服务器等待,我也可以让连接在服务器端sleep).但是连接只能存在于本次请求中.无法保持住.而comet允许连接请求过来后被保持住(保存起来,如session里面).当我需要的时候,读出来再返回给客户端数据.所以这种情况的所谓的"长"长在了服务器端.
长轮询比轮询的好处在于,如果像是即时通讯,聊天室一类的应用,轮询并不能保证每次查阅服务器一定有数据需要返回,所以会造成很多没用的请求到达服务器.而长轮询因为连接保持在了服务器,需要的时候激活就可以.所以就省去了很多没用的请求.
长轮询适合那些数据反映需要及时,但是数据量不大的场景.比如站内消息.其实聊天室不是多么适合.因为人多的时候.长轮询和轮询没啥区别.所以,对于服务器与浏览器交互密集型的实时场景.长轮询并不能减少多余的请求.
长轮询使用ajax实现浏览器响应.其实也可以使用隐藏的iframe来做.毕竟那个奇葩的IE是我们不得不兼容的.
用iframe 模拟ajax请求的这种 叫做 "iframe streaming"
对于交互密集型实时场景.还有没有办法优化.还真有.
对于 Servlet3 的 AsynContext 关闭有两种情况.一种是正常的complete.另一种就是dispatch.
complete很容易理解.完成后.浏览器继续请求一次.这叫长连接.
如果不complete.而dispatch到自身.数据会返回到客户端.但是连接并不需要再次请求.dispatch后的请求仍然可以继续返回到客户端.
所以这种请求方式只需要客户端发起一次请求就可以了.
但是.好事多磨.对于前台来说.由于连接被dispatch.ajax会报错.(据说FF还是op.允许ajax继续处理请求,我试验的chrome,报错了,如果谁成功了,一定告诉我.)
但是.我们可以使用隐藏的iframe来接收这些请求.就可以正常使用了.当然.浏览器的加载按钮会一直转啊转啊..
我个人比较喜欢dispatch这种方式.奇淫技巧很唬人啊.适合忽悠刚入职的小朋友们哈哈..