Files
coin-portal-new/static/new_kline/lib/SocketHandler.js
2025-12-22 13:10:24 +08:00

132 lines
3.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

function SocketHandler(url) {
// 基于H5原生api
this.ws = new WebSocket(url);
// 定义一个信号发射塔,用于发送事件
this.tower = document.createElement('div');
}
SocketHandler.prototype = {
// 订阅频道
channels : {},
// 反应堆用于收集和分发socket的响应
reactions : {},
// 缓存监听事件
events : [],
// 获取当前时间
nowTime : function() {
return new Date().getTime();
},
// 打开socket连接
open : function(heartbeatTimeout) {
this.ws.onopen = function(){
var heartbeatSendInterval = heartbeatTimeout / 2;
this.lastSubscribeTime = this.nowTime();
this.pingIntervalId = setInterval(function(){
var iv = this.nowTime() - this.lastSubscribeTime;
// 超过一定时间自动与后台ping、pong 单位:秒
if ((heartbeatSendInterval + iv) >= heartbeatTimeout) {
this.send('ping');
}
}.bind(this), heartbeatSendInterval);
}.bind(this);
},
// 创建自定义事件
createEvent : function(event, detail){
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent(event, false, false, detail);
return evt;
},
// 打开socket连接
connect: function(heartbeatTimeout) {
this.open(heartbeatTimeout);
this.message();
this.close();
},
// 订阅消息 ch 为订阅的频道 id 为订阅唯一标识
subscribe : function(ch, id, token) {
if(this.ws.readyState == 1) {
var obj = {};
if(ch) {
obj.sub = ch;
obj.id = id;
if(token) obj.authorization = token;
if(this.channels.hasOwnProperty(id)) {
this.unsubscribe.apply(this, Object.values(this.channels[id]));
}
this.channels[id] = obj;
this.reactions[ch] = this.createEvent(id);
this.send(obj);
}
}
},
// 监听订阅结果
on : function(id, callback) {
var handler = function(e) {
if(callback) callback(e.data, e);
};
this.tower.addEventListener(id, handler);
var key = id + '_' + this.nowTime();
this.events.push({key : key, handler: handler});
},
// 取消订阅
unsubscribe : function(ch, id, token) {
if(this.ws.readyState == 1) {
var obj = {};
if(ch) {
obj.cancel = ch;
obj.id = id;
if(token) obj.authorization = token;
if(this.channels.hasOwnProperty(id)) {
delete this.channels[id];
delete this.reactions[ch];
}
this.events = this.events.filter(function(v){
if(v.key.indexOf(id) !== -1) {
// 失效ID解除监听
this.tower.removeEventListener(id, v.handler);
}else{
return v;
}
}.bind(this));
this.send(obj);
}
}
},
send : function(data){
if(typeof data === 'object') {
data = JSON.stringify(data);
}
this.ws.send(data);
},
message : function() {
this.ws.onmessage = function(evt){
var data = evt.data;
this.lastSubscribeTime = this.nowTime();
if(data) {
if(data !== 'pong') data = JSON.parse(data);
if(typeof data === 'object' && data.hasOwnProperty('ch')) {
var e = this.reactions[data.ch];
if(e) {
e.data = data;
this.tower.dispatchEvent(e);
}
}
}
}.bind(this);
},
close : function(callback) {
this.ws.onclose = function(evt){
clearInterval(this.pingIntervalId);
if(callback) callback(evt, this.ws);
}.bind(this);
}
};