php推送
需求:
我想做个会员站内通知的功能。不想用以前的ajax查询,听说有个推技术。以下文章介绍的不错,来自转载,
==================================================================================
PHP中Push(推送)技术的探讨 [http://vistaswx.com/blog/article/php-server-push]
随着人们对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
==============================================================================================
comet研究[http://lync.in/research-on-comet/]
在Web应用中,客户端的AJAX技术已经非常普遍也非常深入人心了,但与此同时,另一些应用,诸如在线监控,实时数据显示,即时通讯等需要将后台
数据变化情况实时显示到前台,这样的由服务器push的行为(也许会让你想到blackberry)则需要另一种方案来解决,也就是本文所要介绍的
Comet —— 无需安装插件,保持http长连接的服务器推方案。
以下两点是方案中必须顾及到的。
- 浏览器通用性,对各种不同实现结构模型的支持。
- 长连接对于服务器资源的占用,以及服务器的承受能力。
Comet的客户端与服务端交互流
业界对于Comet实现有两种主要的解决方案:
基于AJAX的轮询(long polling)方式
这种方式就是由客户端发出AJAX请求,然后服务端阻塞请求直至有响应或超时。客户端在接收到服务端的指令之后会进行响应并发出新的请求。
从实现层面上来说,当XMLHttpRequest的状态为4也就是load的状态时会进行客户端处理,而Gecko(Firefox)和
Webkit(Chrome,Safari)目前支持在readystate为3的时候读取(当然只能读取到所有该请求已返回的串内容,所以需要自行确定
指令边界),Trident(IE)目前如果中途去读取会抛出错误,IE8中使用XDomainRequest可以适当解决这个问题(参见Eric
Law的COMET Streaming in Internet Explorer[])。目前,开心网采用的是这一种方式。
基于iframe及htmlfile的流(streaming)方式
这种方式是使用了iframe的机制,然后使得这个iframe请求一个特定的URL,并通过对这个页面的加载不断的从服务端抓回数据,这里从服务端抓回的数据大多是对页面当前JavaScript函数的引用和操作。
这个方案的一个明显不足之处是页面会一直显示正在加载,而这在IE上会更明显。Google的天才们想到了用htmlfile的ActiveX控件来解决这个问题的方案,详细描述可以参见Alex Russell的What else is burried down in the depth's of Google's amazing JavaScript?
目前,人人网和GTalk采用的是这种方式。
除了文首所提到的通用性和性能之外,还有几点是需要列入考量范围的。
- 数据交换的格式。由于数据交换的形式是推送,所以不可避免的会有指令队列的存在,于是数据结构是需要前后台详细约定的,执行指令和数据指令都需要有严格的界定,一般来说,JSON的方案比较普遍。
- 浏览器本身的连接数限制。HTTP 1.1规范中声明客户端不应该与服务器端建立超过两个的 HTTP 连接,而IE又严格遵守了这一点,所以前台在处理请求的时候需要谨慎控制请求的数量。
其实,Comet技术在AJAX大红大紫的2005年之后的2006年时是业界一个很热的讨论点,目前的这两种方式非常成熟,在dojo,dwr等前端框架中都已经有这样的实现,而Bayeux协议的出现也已经在实质上订下了一种业界的标准。
Comet的框架前端有Pushlet,dwr和dojo等,服务端有Jetty,Meteor,Orbited,Glassfish,Alpha,实现的产品语言也覆盖了Java,C++,Python,Perl,Ruby,Erlang,.Net等。
下一代HTML5中的WebSocket会是Comet的一个新起点,但在那之前,在非插件的web层面应该不会有更进一步的讨论与技术出现。
本文只是对Comet这个技术进行大体的概述,粗陋不明之处难免,在后续的文章中将会对WebSocket进行一定的解释和演示。
参考资料:
- 这里有一个php的comet的例子How to implement COMET with PHP。这个要看看
- 这是developerWorks上对于Comet的介绍。
- 这是当前Comet的服务器端的一些产品及介绍。
- 当然,Wikipedia上面对Comet的解释也是非常详尽。
- 还可以看看AjaxPatterns上面的一些介绍。
- 最后,CometDaily是个值得去了解最新Comet新闻和知识的地方。
- =====================================================================================================
Comet:基于 HTTP 长连接的“服务器推”技术
[http://www.ibm.com/developerworks/cn/web/wa-lo-comet/]
ps:上述文章应该够你看明白的了。使用一种吧。但我现在还没有在项目用推技术,原因,还没有来得及折腾,但在本地测试都很正常 。
以下提供protype 和 jquery的 +php实现的代码例子。[例子代码来自网上,已测试通过。好用]
http://bbs.php100.com/read-htm-tid-290215-ds-1.html
php推送的更多相关文章
- 在Openfire上弄一个简单的推送系统
推送系统 说是推送系统有点大,其实就是一个消息广播功能吧.作用其实也就是由服务端接收到消息然后推送到订阅的客户端. 思路 对于推送最关键的是服务端向客户端发送数据,客户端向服务端订阅自己想要的消息.这 ...
- iOS---iOS10适配iOS当前所有系统的远程推送
一.iOS推送通知简介 众所周知苹果的推送通知从iOS3开始出现, 每一年都会更新一些新的用法. 譬如iOS7出现的Silent remote notifications(远程静默推送), iOS8出 ...
- SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=》提升)
SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=>提升,5个Demo贯彻全篇,感兴趣的玩才是真的学) 官方demo:http://www.asp.net/si ...
- SignalR SelfHost实时消息,集成到web中,实现服务器消息推送
先前用过两次SignalR,但是中途有段时间没弄了,今天重新弄,发现已经忘得差不多了,做个笔记! 首先创建一个控制台项目Nuget添加引用联机搜索:Microsoft.AspNet.SignalR.S ...
- 【原创分享·微信支付】C# MVC 微信支付之微信模板消息推送
微信支付之微信模板消息推送 今天我要跟大家分享的是“模板消息”的推送,这玩意呢,你说用途嘛,那还是真真的牛逼呐.原因在哪?就是因为它是依赖微信生存的呀,所以他能不 ...
- Android 几种消息推送方案总结
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6241354.html 首先看一张国内Top500 Android应用中它们用到的第三方推送以及所占数量: 现 ...
- 基于SignalR的消息推送与二维码描登录实现
1 概要说明 使用微信扫描登录相信大家都不会陌生吧,二维码与手机结合产生了不同应用场景,基于二维码的应用更是比较广泛.为了满足ios.android客户端与web短信平台的结合,特开发了基于Singl ...
- fir.im Weekly - 关于 iOS10 适配、开发、推送的一切
"小程序"来了,微信变成名副其实的 Web OS,新一轮的Web App 与Native App争论四起.程序员对新技术永远保持灵敏的嗅觉和旺盛的好奇心,@李锦发整理了微信小程序资 ...
- ASP.NET SignaiR 实现消息的即时推送,并使用Push.js实现通知
一.使用背景 1. SignalR是什么? ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指 ...
- 极光推送和友盟推送,ios端和安卓端的后端调试设置
我是最后端的,这两天搞了一个app项目,前端安卓使用友盟很方便,调试比较顺利,然后ios就遇到各种问题了,证书.发送成功推送不成功,测试时用的TestMode(),ios上架之后就必须用product ...
随机推荐
- c++ 绘制方框
知识点: GetStdHandle函数 FillConsoleOutputCharacter函数 SetConsoleCursorPosition函数 system函数 一. GetStdHandle ...
- 会话控制(session和cookie)、跨页面传值
1.session 登录上一个页面以后,长时间没有操作,刷新页面以后需要重新登录. 特点:(1)session是存储在服务器: (2)session每个人(登陆者)存一份: (3)session ...
- 2 CRM 讲师与学生,highcharts应用
一.讲师与学生简介 1 初始化 course_record,studyrecord, 2 考勤 3 录入成绩 4 显示成绩 ajax 查询 5 上传作业(os模块) 6 下载作业 二. 初始化 ,st ...
- [COCI2009]Dvapravca 计算几何
[COCI2009]Dvapravca LG传送门 先给出考场上的\(O(n^3)\)乱搞方法:枚举一个蓝点和一个红点,找出过着两个点的直线,再枚举蓝点找出这条直线最多能往两边扩展多宽,最后枚举红点计 ...
- SSISDB1:使用SSISDB管理Package
SSISDB 系列随笔汇总: SSISDB1:使用SSISDB管理Package SSISDB2:SSIS工程的操作实例 SSISDB3:Package的执行实例 SSISDB4:当前正在运行的Pac ...
- 常见面试算法题JS实现-仅用递归函数和栈操作逆序一个栈
前言: 因为JAVA和JS语言特性的不同,有些东西在JAVA中可能需要一些技巧和手段才能实现的复杂程序,但是在JS中可能就是天然存在的,所以这套书里面的题目不会全部用JS去实现一遍,因为可能JS的实现 ...
- 【前端模板之路】一、重构的兄弟说:我才不想看你的代码!把HTML给我交出来!
写在前面 随着前端领域的发展和社会化分工的需要,继前端攻城湿之后,又一重要岗位横空出世——重构攻城湿!所谓的重构攻城湿,他们的一大特点之一,就是精通CSS配置文件的编写...前端攻城湿跟重构攻城湿是一 ...
- Effective C++(Third Edition) Item29 为“异常安全”而努力是值得的
“异常安全”有两个条件: 1.不泄露任何资源 可以通过以对象管理资源的方式(Item13). 2.不允许数据败坏 异常安全函数提供以下三种保证之一 a.基本承诺 如果异常被抛出,程序内的任何事物都仍然 ...
- redmine on centos
一 前言 前前后后搭建redmine,花费了很多时间.期间会遇到各种坑,因此总结下自己的方法,分享给各位童鞋. 二 操作系统 centos release 6.9 详细信息如下图: 三 安装步骤 ...
- SSM搭项目报错:HTTP Status 400 – Bad Request
具体报错如下: Type Status Report Description The server cannot or will not process the request due to some ...