PHP ServerPush
原文:http://yorsal.com/archives/302
随着人们对Web即时应用需求的不断上升,Server Push(推送)技术在聊天、消息提醒尤其是社交网络等方面开始兴起,成为实时应用的数据流核心。这篇日志试图探讨的便是各种适合于PHP的Push的实现方式以及其优劣。
1. 什么是Server Push
想象在聊天应用中,如果使用传统的ajax来承担消息的传入,那么一般是通过每隔一定时间拉取一次信息的方式实现,但是其实这种方式有大量查询是浪费的。聊天等Web应用更需要服务器在特定时间来主动告知前端有新的消息(Push),而不是前端每时每刻问服务器:“来消息了吗?”(Pull)。这也正是为什么这个技术常被叫做反向ajax。
其他别名:Comet,反向Ajax
2. 如何实现Push
其实所谓的推送技术也没有多么复杂,目前从大类上有3种,一种仍然建立在ajax基础上,还有一种建立在框架基础上,最后一种抛弃了传统的HTTP协议,使用Flash或者HTML5的WebSockets技术。接下来将对这三种类别产生的不同的方式进行探讨。
1) Ajax 长轮询
Ajax长轮询从本质上来说仍然是一种pull,但是实时性较高,无用请求减少很多,是一种不错的Push实现方案。不过它只减少了网络上的无谓消耗。
核心: 客户端发起一个ajax请求,服务端将请求搁置(pending)或者说挂起,直到到了超时时间(timeout)或需要推送时返回;客户端则等待ajax返回后处理数据,再发起下一个ajax请求。
优点: 兼容性较高,实现简单
缺点: 对于php这种语言来说,如果要做到实时,那么服务端就要承受大得多的压力,因为搁置到什么时候往往是不确定的,这就要php脚本每次搁置都进行一个while循环。
当然,如果服务器刷新每秒级,那尚可接受,只是实时性上退化了。
注意: 浏览器有连接数限制。我得出的结论是如果当前页面上有一个ajax请求处于等待返回状态,那么其他ajax请求都会被搁置(Chrome, Firefox已测)。如果页面有一般ajax需求怎么办?解决方法是开个框架,框架中使在另一个域名下进行Comet长轮询,需要注意跨域问题。
PHP实现: Jquery+php实现comet
2) Frame 长连接
受到ajax启发,出现了框架下的长连接。
核心: Frame中发起一个普通请求,服务器将其搁置;需要推送时输出直接执行
脚本,然后继续保持连接。如果担心超时问题可以改成框架论询。
优点: 与1一样具有高兼容特性
缺点: 最大的问题是如果框架在载入,那么浏览器就好一直显示“载入中”,这就弱爆了(解决方法参见文末的相关阅读资源)。同样服务器也要能hold住大量循环……另外,是否有同域连接限制没测试。
3) Flash/HTML5 WebSockets
用flash来发起WebSockets,秒杀前面一切问题。
优点: 标准化, RealTime, Push
缺点: 服务器需要能应对WebSockets;还有如果既没有Flash又不支持HTML5的怎么办?
PHP实现: Start Using HTML5 WebSockets Today
6) 使用兼容封装层(socket.io)
以上每种方法都有优劣,那么终极解决方案便是合在一起!能WebSockets时候就WebSockets,不支持HTML5特性就退化到Flash,没有Flash则退化到Ajax长轮询。这也是我的Rainbowfish所采用的方式。
优点: 高度封装,编写非常容易,几乎不需要关心如何去实现的。实时,超低负载,高并发。
缺点: 其实算不上缺点,socket.io的服务器端要求是node.js,而不是php。
个人看法: 如果你是独立主机,能运行程序,那么socket.io配合node.js是个非常高效的选择。为什么呢?因为它还可以避免php的服务端高负载。
Rainbowfish的消息系统通过这种方式实现: 所有客户端都通过socket.io挂在nodejs服务器上(注意: 只是挂着,不需要任何循环,因为它是事件驱动的);需要推送消息了,服务器就与nodejs通信(比如访问某个地址来实现),告诉它推送什么消息到哪里;nodejs收到推送信号后,则通过socket.io实时传输数据给浏览器。这个其实也是一条单向的路,因为nodejs服务器不具备与php通信的能力,实际上也不需要,网页上直接连php就可以了。
3. 结束语
事实上,第一个方法(Ajax Long Pull)是一个不错的方法,只是如果使用php完成的话服务器负载上有点大,但这其实是通病;而最后列举的socket.io方案完全避免了这个问题,因为它属于另一种架构,并且这种组合也可以配合几乎所有的脚本语言实现push。
对于实时性要求非常高的应用,或许使用php实现实时部分并不是一个好的选择,将会面临非常大的服务器负载(可以通过编写支持等待事件的扩展来解决这个问题);如果只是消息提示等,则可以调整服务器上刷新的间隔降低到秒的级别,负载尚可接受。不过无论哪种用途,配合那些非阻塞语言或许才是最好的选择。
4. 相关阅读
How to implement COMET with PHP
Start Using HTML5 WebSockets Today
PHP ServerPush的更多相关文章
- PHP ServerPush (推送) 技术的探讨
2016年11月29日17:51:03 转自:http://www.cnblogs.com/hnrainll/archive/2013/05/07/3064874.html 需求: 我想做个会员站内通 ...
- PHP ServerPush <转>
http://www.cnblogs.com/hnrainll/archive/2013/05/07/3064874.html
- PHP ServerPush (推送) 技术
用来代替ajax的请求 转自:http://blog.163.com/bailin_li/blog/static/17449017920124811524364/ 需求: 我想做个会员站内通知的功能. ...
- PHP ServerPush (推送) 技术的探讨[整理]
需求: 我想做个会员站内通知的功能.不想用以前的ajax查询,听说有个推技术.以下文章介绍的不错,来自转载, ============================================= ...
- PHP ServerPush (推送) 技术的探讨【转】
随着人们对Web即时应用需求的不断上升,Server Push(推送)技术在聊天.消息提醒尤其是社交网络等方面开始兴起,成为实时应用的数据流核心.这篇日志试图探讨的便是各种适合于PHP的Push的实现 ...
- 【干货分享】前端面试知识点锦集04(Others篇)——附答案
四.Others部分 技术类 1.http状态码有哪些?分别代表是什么意思? (1).成功2×× 成功处理了请求的状态码.200 服务器已成功处理了请求并提供了请求的网页.204 服务器成功处理了请求 ...
- h5面试题集合
一.闭包的理解: 使用闭包主要是为了设计私有的方法和变量.闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露. 闭包三个特性: 1.函数嵌套函数 ; ...
- 使用php+swoole对client数据实时更新(下)
上一篇提到了swoole的基本使用,现在通过几行基本的语句来实现比较复杂的逻辑操作: 先说一下业务场景.我们目前的大多数应用都是以服务端+接口+客户端的方式去协调工作的,这样的好处在于不论是处在何种终 ...
- 使用php+swoole对client数据实时更新(上)
如果想对一个列表做实时的更新,传统的做法是采用轮询的方式.以web为例,通过Ajax定时请求服务端然后获取数据显示在页面.这种方式实现简单,缺点就是浪费资源. HTTP1.1新增加了对websocke ...
随机推荐
- Ueditor 1.4.3 单独调用上传图片,或文件功能
第一步, 引入文件 <script src="ueditor/ueditor.config.js" type="text/javascript" char ...
- PHP使用empty检查函数返回结果时报Fatal error: Can't use function return value in write context的问题
PHP开发时,当你使用empty检查一个函数返回的结果时会报错:Fatal error: Can't use function return value in write context 例如: &l ...
- 8款功能强大的最新HTML5特效实例
1.HTML5 Canvas画板画图工具 可定义笔刷和画布 今天要分享的这款HTML5 Canvas画图工具就可以简单实现网络画图的功能,我们可以自定义笔刷的类型.粗细.颜色,也可以定义画布的大小和背 ...
- 【风马一族_Android】第4章Android常用基本控件
第4章Android常用基本控件 控件是Android用户界面中的一个个组成元素,在介绍它们之前,读者必须了解所有控件的父类View(视图),它好比一个盛放控件的容器. 4.1View类概述 对于一个 ...
- 《samba搭建win客户端和linux客户端的区别》
samba服务的搭建 客户的使用系统的不同也导致测试结果的不同. linux系统客户端: security = user or share smbclient -L //192.168.7.113/w ...
- 自己手写简约实用的Jquery tabs插件(基于bootstrap环境)
一直想改版网站首页的图书展示部分,以前的展示是使用BootStrap的传统的collapse,网页篇幅占用大,也不够美观,操作也相对来说比较麻烦.于是有了自己利用Jquery来做一个图书展示的tabs ...
- 33选6算法:M个数N个为一组,无重复的排列组合
private void button1_Click(object sender, EventArgs e) { int nCnt = 0; List nNumList = new List(); f ...
- centos中安装chromium和flash
安装环境:centos 6.5 64位 在centos中安装chromium 安装Google源 cd /etc/yum.repos.d/ sudo wget http://people.CentOS ...
- Stanford parser:入门使用
一.stanford parser是什么? stanford parser是stanford nlp小组提供的一系列工具之一,能够用来完成语法分析任务.支持英文.中文.德文.法文.阿拉伯文等多种语言. ...
- Oracle 表的连接方式(2)-----HASH JOIN的基本机制2
Hash算法原理 对于什么是Hash算法原理?这个问题有点难度,不是很好说清楚,来做一个比喻吧:我们有很多的小猪,每个的体重都不一样,假设体重分布比较平均(我们考虑到公斤级别),我们按照体重来分,划分 ...