let socket = null;
let socketUrl = '';
let timeoutObj = null;
let global_callback = null; // 回调函数-用来调用socket的方法
/**建立连接 */
export const createSocket = (url) => {
if (!socket) {
socket = new WebSocket(url);
socketUrl = url;
socket.onopen = onopenWS;
socket.onerror = onerrorWS;
socket.onclose = oncloseWS;
socket.onmessage = onmessageWS;
}
};
/**接收的消息回调*/
export const getMessage = (callback) => {
global_callback = callback;
};
/**关闭连接*/
export const closeSocket = () => {
socket.close();
};
/**打开WS之后发送心跳 */
const onopenWS = () => {
sendPing();
};
/**失败重连 */
const onerrorWS = () => {
console.log('连接失败');
reconnect();
};
/**断开连接 */
const oncloseWS = () => {
console.log('断开连接');
};
/**接收消息 */
const onmessageWS = (e) => {
// 如果接收到的消息不是心跳消息,则立刻重置心跳时间,并再次发起一次心跳
// 避免了传统的轮询心跳带来的不必要的损耗
// 如果接收到的消息是心跳消息,则会继续发送心跳,保持连接畅通
clearTimeout(timeoutObj);
sendPing();
// 这里把接收到的消息传入到回调函数中,在组件内可获取接收的消息
global_callback && global_callback(e);
};
/**
* 发送数据但连接未建立时进行处理等待重发
* @param {any} message 需要发送的数据
*/
const connecting = message => {
setTimeout(() => {
if (socket.readyState === 0) {
connecting(message);
} else {
socket.send(JSON.stringify(message));
}
}, 1000);
};
/**
* 发送数据
* @param {any} message 需要发送的数据
*/
export const sendWSPush = message => {
if (socket.readyState === 1) {
socket.send(JSON.stringify(message));
} else if (socket.readyState === 0) {
connecting(message);
}
};
/**发送心跳 */
const sendPing = () => {
let params = {
'cmd': 1001,
'time': new Date().getTime(),
'message': 'ping'
};
timeoutObj = setTimeout(() => {
if (socket.readyState === 1) {
socket.send(JSON.stringify(params));
} else {
reconnect();
}
}, 20000);
};
/**重新连接
*每五秒重连一次,避免频繁的重连
*/
const reconnect = () => {
setTimeout(() => {
socket = null;
createSocket(socketUrl);
}, 5000);
};