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中提出的新的协议,注意,这里是协议,可以 ...
随机推荐
- 目录服务不能与此服务器复制,因为距上一次与此服务器复制的时间已经超过了 tombstone 生存时间。
1.PDC数据正常 2.其他DC无法复制,报如下错误:目录服务不能与此服务器复制,因为距上一次与此服务器复制的时间已经超过了 tombstone 生存时间. 3.直接强制复制即可 repadmin / ...
- centos通过yum安装php
1.添加php的yum软件仓库 sudo rpm -Uvh https://mirror.webtatic.com/yum/el6/latest.rpm 2.安装php相关软件,执行过程中全部选择ye ...
- 无车承运前世今生,5G货运管家期待您的加入
历时三年的无车承运人试点工作结束,从2020年1月1日起,将执行新的暂行<办法>,在这样一个承前启后的阶段,无车承运人的命运如何?网络货运经营者又是何物? 在新赛道下,将迎来什么样的机遇和 ...
- JAVA 算法练习(二)
和上次一样,虽说用 java 语言,但有 c 的基础一样可以看懂哦. 机器人走方格问题Ⅰ 题目概述 有一个XxY的网格,一个机器人只能走格点且只能向右或向下走,要从左上角走到右下角.请设计一个算法,计 ...
- 题解 P4942 【小凯的数字】
题目 为什么看到很多题解区的 dalao 都用逆元?是我太菜了吧 [分析] 首先,根据弃九验算法的原理,显然可以得到:一个 \(n\) 位数 \(a_1a_2a_3\dots a_n\equiv a_ ...
- 复杂分布式架构下的计算治理之路:计算中间件 Linkis
前言 在当前的复杂分布式架构环境下,服务治理已经大行其道.但目光往下一层,从上层 APP.Service,到底层计算引擎这一层面,却还是各个引擎各自为政,Client-Server 模式紧耦合满天飞的 ...
- 吴裕雄--天生自然Linux操作系统:Linux 磁盘管理
Linux磁盘管理好坏直接关系到整个系统的性能问题. Linux磁盘管理常用三个命令为df.du和fdisk. df:列出文件系统的整体磁盘使用量 du:检查磁盘空间使用量 fdisk:用于磁盘分区 ...
- java生成6位数所有组合
for(int i=0;i<=9;i++){ String str=""; str=str+i; String strj=""; for(int j=0; ...
- MyBatis从入门到精通(第5章):MyBatis代码生成器
jdk1.8.MyBatis3.4.6.MySQL数据库5.6.45.Eclipse Version: 2019-12 M2 (4.14.0) MyBatis从入门到精通(第5章):MyBatis代码 ...
- ae基础二
纯色文本操作快捷键:选中图层点击快捷键(变换)锚点:a(调节中心点)位置:p(左右移动)(利用位置k帧做动画)缩放:s(水平翻转垂直翻转)旋转:r(围绕中心点(锚点)进行旋转)不透明度:tu选中索引 ...