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中提出的新的协议,注意,这里是协议,可以 ...
随机推荐
- [前端] VUE基础 (8) (vue-cli脚手架)
一.安装vue-cli脚手架 官方文档:https://cli.vuejs.org/zh/guide/cli-service.html Vue CLI 的包名称由 vue-cli改成了 @vue/c ...
- 为什么声明了int型的变量并且直接初始化后,int型变量的地址一直在变化?
/************************************************************************* > File Name: ptr_varia ...
- Linux(CENTOS7) Nginx负载均衡简单配置
负载均衡的作用 1.转发功能 按照一定的算法[权重.轮询],将客户端请求转发到不同应用服务器上,减轻单个服务器压力,提高系统并发量. 2.故障移除 通过心跳检测的方式,判断应用服务器当前是否可以正常工 ...
- 21. docker 数据通讯环境准备
一 . 环境搭建 1.编写 Vagrantfile 并创建虚拟机 并虚拟机host绑定外部 192.168.205.10:8888 # -*- mode: ruby -*- # vi: set ft= ...
- windows下python自带的pip安装速度过慢解决方案
自带下载地址为国外源下载速度时常在20KB以内切换为国内源直接满速! 国内源: 新版ubuntu要求使用https源,要注意. 清华:https://pypi.tuna.tsinghua.edu.cn ...
- springboot的http监控接口启动器的配置
基于SpringBoot框架企业级应用系统开发全面实战()->03.07_http监控_recv.mp4 监控接口启动器 自定义监控接口启动器的配置 ====================== ...
- 12 Spring Data JPA:springDataJpa的运行原理以及基本操作(下)
spring data jpaday1:orm思想和hibernate以及jpa的概述和jpa的基本操作 day2:springdatajpa的运行原理 day2:springdatajpa的基本操作 ...
- UINavigationbar跳转黑色
bug效果:导航栏过渡出现黑色
- JAVA--Mybatis-Spring-SpringMVC框架整合
------Mybatis-Spring-SpringMVC框架整合示例----- mybatis SQL映射文件 <?xml version="1.0" encoding= ...
- Python模块——json
简介 json全名是JavaScript Object Notation(即:Javascript对象标记).它是JavaScript的子集,JSON是轻量级的文本数据交换格式.前端和后端进行数据交互 ...