您的位置:首页 > 其它

长轮询实现消息推送

2014-09-20 10:32 225 查看
一、应用场景 浏览器与服务器之间保持一个长连接(http链接),服务器有最新的数据生成时及时推送到前端展现。典型场景:新邮件到达通知。   二、业界常用的解决方案 定时轮询,长轮询,websocket(HTML5新增的能力) 其中长轮询兼容性较好,应用的较为广泛,但是切忌在移动网络中应用该技术。   三、长连接前端代码
/**
*pns模型层
*@constructs M2012.Model.Pns.PnsModel
*@extends Backbone.Model
*@example
*new M2012.Model.Pns().startRequestPns();
*/
M139.namespace("M2012.Model.Pns", {
PnsModel : Backbone.Model.extend({
callApi : M139.RichMail.API.call,
pnsUrl : '/pns/poll?sid=' + top.sid + '&comeFrom=1003', // PNS接口地址负责推送消息到前端
pnsErrorInterval : 1000 * 120, // 接口报错后下一次重新调接口的时间间隔
pnsTimer : null, // 接口报错后需要用定时器再调一次接口,pnsTimer用于报错定时器ID
msgTypes : {//pns推送过来的消息类型
mailMsg : 70
},
logger : new top.M139.Logger({
name : "M2012.Model.Pns"
}),
initialize : function() {
$App.registerModel("pnsModel", this);
},

startRequestPns : function() {
var self = this;

var options = {};
options.method = 'get';
options.timeout = self.pnsErrorInterval;
options.error = function() {
self.callPns();
self.logger.error("newMailArrival callPns error");
};
options.ontimeout = function() {
self.callPns();
self.logger.error("newMailArrival callPns timeout");
};
options.isSendClientLog = false;

M139.RichMail.API.call(self.pnsUrl, null, function(e) {
var result = e.responseData;
if (result) {
console.log(result);
if (result.errorCode) {
self.callPns();
self.logger.error("newMailArrival returndata error", "[pns/poll]", result);
} else {
self.pnsResultHandle(result);
$App.trigger("pnsNewArrival", result);
//留给以后扩展
self.callPns(500);
//self.autoReceiveMail();
}
} else {
self.callPns();
self.logger.error("newMailArrival returndata error", "[pns/poll]", result);
}
}, options);
},

callPns : function(seconds) {
var self = this;

// 判断用户是否登录超时
if (top.$App.isSessionOut()) {
console.log('登录超时!不再请求PNS');
return;
}

if (self.pnsTimer) {
clearTimeout(self.pnsTimer);
}
self.pnsTimer = setTimeout(function() {
self.startRequestPns();
}, seconds || self.pnsErrorInterval);
},

/*
* 此函数可用于单元测试
* $App.getModel("pnsModel").pnsResultHandle({});
*/
pnsResultHandle : function(result) {
var self = this;
if (result.c > 0) {//c代表数量
var msgArr = result.msg;
for (var i = 0, l = msgArr.length; i < l; i++) {
// TODO 根据消息类型处理业务逻辑
}
} else if (result.c == 0) {
console.log('超时返回!autoReceiveMail');
}
}
})
});
  四、异常捕获及应用服务器 (1)客户端捕获到xhr的error事件或者接口超时之后可500毫秒之后开始下次轮询。 (2)服务端接口报错,不要立即开始下次轮询,可考虑2分钟甚至更长时间后再开始轮询,因为服务端通常需要较长时间恢复正常。 (3)服务端要保持大量的长连接通常需要用特殊的应用服务器,比如:jetty 。tomcat是肯定不行的。   五、参考资料 书籍:《web性能权威指南》 竞品:163邮箱收信  

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: