上一篇写到了小程序websocket的封装,所以这里就不写web端的websocket封装,原理都一样,因为还会还会考虑ie低版本的问题,所以写一下长轮询
(function(){
var websoket = {}
//comet
(function(){
var comet = (function(){
function comet() { }
var cometObj = {
heart_timer: null,
heartBeat: 5000,
alive: false
}
var handleAction = {};
// 短链接,一般拉一次
comet.onopen = function (params) {
ajax({
type: "post",
dataType: "text",
url: '',
data: params,
success: function (message, textStatus) {
var data,act; //这里data也是根据message反序列化然后做的数据处理拿到,act也是处理后的响应标识
var gbCallback = handleAction[act]
gbCallback && gbCallback.onSuccess(data)
},
error: function (textStatus) {
if (textStatus == 401) {
ajaxLoop({
type: "get",
dataType: "text",
url: '',
success: function (data) {
var res = JSON.parse(data);
res.code == 0 && comet.onopen(res.data.token);
}
})
}
}
})
};
// 长轮询
comet.loop = function () {
let bytes; //请求参数序列化得到bytes
ajaxLoop({
type: "post",
dataType: "text",
url: '',
data: bytes,
timeout: 100000,
success: function (message, textStatus) {
//发送数据成功
_this.loop();
},
loading: function (message, textStatus) {
var dataAt = message.replace(window.cometStr, '');
var data = dataAt.split('\r\n');
window.cometStr = message
if (data[0] == 0) {
return
}
//这部分是后台给的串,需要拆分组合,这里需要进行后台沟通情况可能不同
res = Base64.decode(data[1]) // import { Base64 } from 'js-base64';需要自己安装一下
if (res) {
var str2ab = string2buffer(res)
var data,act; //这里data也是根据str2ab 序列化然后做的数据处理拿到,act也是处理后的响应标识
var gbCallback = handleAction[act]
gbCallback && gbCallback.onSuccess(data)
}
},
error: function (textStatus) {
if (textStatus == 401) {
ajaxLoop({
type: "get",
dataType: "text",
url: '',
success: function (data) {
var res = JSON.parse(data);
res.code == 0 && comet.loop(res.data.token);
}
})
} else {
window.errorCount++;
if (window.errorCount <= 10 && !window.conClose) {
setTimeout(() => {
comet.loop(websoket._config.token);
}, 15000);
}
}
}
})
};
/* 初始化 */
comet.init = function (params,callback) {
let bytes //这里把请求进行序列化二进制
let callbackMap = new Map([
'key':'value'
])
let num = callbackMap.get('key') //主要是把请求和响应的方法对应上(为了响应时能找到)
handleAction.set(num, callback)
_this.onopen(params)
};
/* 心跳事件 */
comet.onheartbeat = function (func) {
//在连接状态下
if (true == cometObj.alive) {
/* 心跳计时器 */
cometObj.heart_timer = setInterval(() => {
//发送心跳信息
comet.loop()
console.log(cometObj.heartBeat)
}, cometObj.heartBeat)
}
};
return comet;
}())
websoket.comet = comet
})(websoket);
return websoket
}())
ajax ajaxLoop 是我用原生ajax封装的两个请求
ajax 这个是正常 xmlhttp.readyState == 4 时返回success
ajaxLoop 这个是对 xmlhttp.readyState == 3 时返回loading