COMET探索系列二【Ajax轮询复用模型】
写在前面:Ajax轮询相信大家都信手拈来在用,可是有这么一个问题,如果一个网站中同时有好多个地方需要用到这种轮询呢?就拿我们网站来说,有一个未读消息数提醒、还有一个时实时加载最新说说、昨天又加了一个全网喊话,以后还会要有类似功能添加是肯定的,难道要为每个功能都创建一个独立的轮询?要知道轮询请求中有大半是无用,会对服务器资源和宽带造成巨大的浪费。因此在页面中每增加一个轮询点,对服务器的压力及宽带浪费都将成倍的增长。再考虑一个情况,如果当前网页中需要的不仅是简单的Ajax轮询,而是Ajax长轮询呢?比如在一个 WebIM 应用中同时与两个好友聊天,是不是要为每个好友都建立一个长轮询呢?这不科学,这也不现实,HTTP1.1 协议中规定,同一客户端同一时间最多只能与服务器保持两个连接,问题就变得很棘手了。于是想,所有的轮询无非都是定时向服务器取消息,那么我们是不是只建立一个轮询点定时向服务器取消息,而服务器则将客户端所有需要的消息整理打包后一次性发送给该轮询点,再由该轮询点对返回的消息进行逐点分配处理,心动不如行动,程序员用代码说话。
<!--客户端代码--> var rtmsg = { //请求地址 uri: U("public/RtMsg/rtmsg"), //要获取的消息,可以根据需要动态增减,如从模板变量进行分配,这样可以减少不必要的数据浪费宽带 items:'UnreadCount,Allnet,newfeed', //建立连接 connect: function () { $.ajax({ url: rtmsg.uri, data:{'items':rtmsg.items}, type: 'post', dataType: 'json', success: function (res) { //请求成功后通过HadnleRes对返回的结果进行分配处理 rtmsg.HandleRes(res.data); } }) }, //将取回的结果分配给对应的处理程序 HandleRes: function (res) { for (x in res) { eval('rtmsg.Handle' + x + '(res[x])'); } }, //处理未读消息数提醒 HandleUnreadCount: function (res) { /*…………*/ }, //处理全网喊话 HandleAllnet: function (allnet) { /*…………*/ }, //最新说说处理 HandleNewfeed: function (newfeed) { /*…………*/ } /*我还想要*/ /*我还可以再加*/ }; $(function () { //每隔10秒再来一次 setInterval(rtmsg.connect, 10000); //页面加载完毕先来一次 rtmsg.connect(); })
<!--服务器端程序,注:我这里使用的是ThinkPHP框架-->
<?php
/**
* 实时消息推送模块
*/
class RtMsgAction extends Action
{
/**
* 模块初始化
*/
function _initialize()
{
//关闭session,连接占用session导至页面等待
session_write_close();
//不限请求超时
set_time_limit(0);
} public function rtmsg()
{
//接收要获取的消息项
$items = $_REQUEST['items'];
//收集消息
$rt = $this->collect(explode(',', $items));
//返回的消息格式大至如下
$rt = array(
'UnreadCount'=>array('status'=>1,'data'=>array('total'=>5,'system'=>2,'message'=>3)),
'Allnet'=>array('status'=>1,'data'=>array('消息一','消息二','消息三','data格式自定,方便客户端处理为好'),
'Newfeed'=>array('status'=>0,'data'=>false)
)
//返回json格式消息
echo json_encode($rt);
} /**
* 收集需要返回给客户端的信息
*/
public function collect($items)
{
//设置未传items时默认获取哪些消息
$items = $items?$items:array('UnreadCount', 'Allnet', 'Newfeed');
$rt = array();
//逐项获取消息
foreach ($items as $v) {
$rt[$v] = call_user_func(array(&$this, 'get' . $v));
} return $rt;
} /**
* 获取用户的通知统计数目
*/
public function getUnreadCount()
{
/*获取消息过程省略,返回信息格式如下*/
$data['status'] = '获取信息状态';
$data['data'] = '信息详情';
return $data;
} /**
* 获取全网喊话
*/
public function getAllnet()
{
/*获取消息过程省略,返回信息格式如下*/
$data['status'] = '获取信息状态';
$data['data'] = '信息详情';
return $data;
} /**
* 获取最新说说
*/
public function getNewfeed()
{
/*获取消息过程省略,返回信息格式如下*/
$data['status'] = '获取信息状态';
$data['data'] = '信息详情';
return $data;
} }
基实本模型的关键在于各消息的分类收集,及返回消息之后的分配处理,即代码中以下两个部分
//客户端:将取回的结果分配给对应的处理程序 HandleRes: function (res) { for (x in res) { eval('rtmsg.Handle' + x + '(res[x])'); } }
//服务器端:逐项收集信息 foreach ($items as $v) { $rt[$v] = call_user_func(array(&$this, 'get' . $v)); }
至此Ajax轮询复用模型就建好了,技术没什么技术,关键是巧合,最后总结一下这种模型的优缺点。
优点:避免了客户端多个轮询点造成的服务器资源及宽带浪费,可以动态更改需要获取的消息项,便于管理。
缺点:没有办法为每个需要轮询的点分配独立的请求频率,一般情况下无所谓啦,如果是在长轮询中使用该缺点不复存在。
本文纯属原创,转载请注明出处。
COMET探索系列二【Ajax轮询复用模型】的更多相关文章
- Ajax轮询以及Comet模式—写在Servlet 3.0发布之前(转)
2008 年的夏天,偶然在网上闲逛的时候发现了 Comet 技术,人云亦云间,姑且认为它是由 Dojo 的 Alex Russell 在 2006 年提出.在阅读了大量的资料后,萌发出写篇 blog ...
- 【Javascript】解决Ajax轮询造成的线程阻塞问题(过渡方案)
一.背景 开发Web平台时,经常会需要定时向服务器轮询获取数据状态,并且通常不仅只开一个轮询,而是根据业务需要会产生数个轮询.这种情况下,性能低下的Ajax长轮询已经不能满足需求,频繁的访问还会造成线 ...
- Android学习系列(7)--App轮询服务器消息
这篇文章是android开发人员的必备知识. 1.轮询服务器 一般的应用,定时通知消息可以采用轮询的方法从服务器拿取消息,当然实时消息通知的话,建议采用推送服务. 其中需要注意轮询的频率 ...
- WebSocket原理及与http1.0/1.1 long poll和 ajax轮询的区别【转自知乎】
一.WebSocket是HTML5出的东西(协议),也就是说HTTP协议没有变化,或者说没关系,但HTTP是不支持持久连接的(长连接,循环连接的不算)首先HTTP有1.1和1.0之说,也就是所谓的ke ...
- ajax轮询与长轮询
刚刚网了关于轮询的知识,必须拿到自己这里来做个备份了! 其实以前用ajax轮询做个及时数据更新的,只是当时做了不知道那个就是轮询. 首先我们什么时候会想到用轮询技术呢? 一般而言,最多的是及时信息 ...
- WebSocket和long poll、ajax轮询的区别,ws协议测试
WebSocket和long poll.ajax轮询的区别,ws协议测试 WebSocket是HTML5出的东西(协议),也就是说HTTP协议没有变化,或者说没关系,但HTTP是不支持持久连接的(长连 ...
- long poll、ajax轮询和WebSocket
websocket 的认识深刻有木有.所以转到我博客里,分享一下.比较喜欢看这种博客,读起来很轻松,不枯燥,没有布道师的阵仗,纯粹为分享.废话这么多了,最后再赞一个~ WebSocket是出的东西(协 ...
- COMET探索系列一【COMET实践笔记】
这几天在给公司的一个点对点聊天系统升级,之前只是使用简单的ajax轮询方式实现,每5秒钟取一次数据,延时太长,用户体验不是很好,因此打算采用服务器推送技术,故此整理了以下文档,将自己找到的一些资料及心 ...
- 浅谈Websocket、Ajax轮询和长连接(long pull)
最近看到了一些介绍Websocket的文章,觉得挺有用,所以在这里将自己的对其三者的理解记录一下. 1.什么是Websocket Websocket是HTML5中提出的新的协议,注意,这里是协议,可以 ...
随机推荐
- 用tkinter写一个记事本程序(未完成)
之前在看tkinter与python编程 ,后面学opengl就把那本书搁置了.几天没用tkinter,怕是基本的创建组件那些都忘记了,所以想着用tkinter试着写一下记事本程序.一开始的时候以为很 ...
- CodeForces-1100C NN and the Optical Illusion 简单数学
题目链接:https://vjudge.net/problem/CodeForces-1100C 题意: 题目给出外部圆的数目n和内部圆的半径r,要求求出外部圆的半径以满足图片要求. 显然这是一道数学 ...
- awk中传参方式
结合编辑数据文件的shell脚本学习awk传参方式,该脚本功能: a.取VIDEOUSR_11082017_0102_ONLINE_STASTIC.dat文件中第87个字段的低8位: b.将每行数据的 ...
- Hexo博客NexT主题美化之评论系统
前言 更多效果展示,请访问我的博客 https://kangmingxian.github.io/ 效果图: image Valine 诞生于2017年8月7日,是一款基于Leancloud的快速 ...
- Mac系统的SVN客户端:Snail SVN 精简版
Mac系统的SVN客户端:Snail SVN 精简版 前言 本人在公司中,使用的是windows操作系统,svn客户端自然也就使用tortoise svn.但自从男朋友给我买了台macbook pro ...
- 17。3.12---re模块--正则表达式操作指南
1----python re模块(Regular Expressioin正则表达式)提供了一个与perl等编程语言类似的正则匹配操作,他是一个处理python字符串的强有力的工具,有自己的语法和独立的 ...
- unity学习 5.x依赖打包和解包
unity5已经封装好了接口,所以依赖打包并没有那么神秘和复杂了. 打包: 1.定义好资源的assetBundleName 2.BuildPipeline.BuildAssetBundles,指定资源 ...
- Java之同步方法处理继承Thread类的线程安全问题
/** * 使用同步方法处理继承Thread类的方式中的线程安全问题 * */class Window4 extends Thread { private static int ticket = 10 ...
- long型长整数字在前端页面显示异常及其解决方法
文章目录 1.引子 2.解决问题 (1)初试EL表达式取long型数值 (2)再探EL表达式取字符串格式long型数值 (3)最后一试---给EL表达式加引号 3.总结 1.引子 在做项目中,发现了一 ...
- oracle 学习(五)pl/sql语言存储过程&包
首先搞清楚俩概念 存储过程(procedure)&程序包(package) 存储过程:数据库对象之一,可以理解为数据库的子程序,在客户端和服务器端可以直接调用它.触发器是与表直接关联的特殊存储 ...