You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
3.7 KiB
149 lines
3.7 KiB
4 years ago
|
let connected = false; // socket 是否连接
|
||
|
let socket = null; // websocket 实例
|
||
|
let lockSocket = false;
|
||
|
let socketMsgQueue = []; // socket消息队列
|
||
|
let prevTimestamp = 0; // 上次收到消息的时间戳
|
||
|
let sendHeartTimer = null; // 💓的timer计时器
|
||
|
let ws = null;
|
||
|
|
||
|
initSocket();
|
||
|
|
||
|
function initSocket() {
|
||
|
if (lockSocket) return;
|
||
|
lockSocket = true;
|
||
|
ws = new WebSocket('wss://www.tall.wiki/websocket/recovery/recovery/ws');
|
||
|
ws.onopen = onOpen;
|
||
|
ws.onmessage = onMessage;
|
||
|
ws.onclose = onClose;
|
||
|
lockSocket = false;
|
||
|
}
|
||
|
|
||
|
// ws 打开
|
||
|
function onOpen(event) {
|
||
|
connected = true;
|
||
|
prevTimestamp = Date.now();
|
||
|
auth(); // 认证
|
||
|
for (let i = 0; i < socketMsgQueue.length; i += 1) {
|
||
|
send(socketMsgQueue[i]);
|
||
|
}
|
||
|
socketMsgQueue = [];
|
||
|
}
|
||
|
|
||
|
// ws收到消息
|
||
|
function onMessage(res) {
|
||
|
try {
|
||
|
prevTimestamp = Date.now();
|
||
|
// console.warn('message: ', res, new Date().toLocaleString());
|
||
|
if (res && res.data && JSON.parse(res.data)) {
|
||
|
const resData = JSON.parse(res.data);
|
||
|
const { messageSet, ackId } = resData;
|
||
|
// 处理消息体对象
|
||
|
messageSet.forEach(item => handleMessagesData(item));
|
||
|
// console.log('ackId', ackId);
|
||
|
// 有ackId 发送ack
|
||
|
ackId && send({ type: 'Ack', data: { ackId } });
|
||
|
}
|
||
|
} catch (error) {
|
||
|
console.error(error);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 处理收到的消息内容
|
||
|
* @param {object} item 单个消息体对象
|
||
|
*/
|
||
|
function handleMessagesData(item) {
|
||
|
const data = JSON.parse(item.data);
|
||
|
switch (data.type) {
|
||
|
case 'ChannelStatus': // 认证消息
|
||
|
handleAuthMessage(data);
|
||
|
break;
|
||
|
case 'feedback': // 收到拔萝卜的动作反馈
|
||
|
console.log('score', data.data.score)
|
||
|
data.data && data.data.result === 1 && handlePull(data.data.times);
|
||
|
onScoreMessage(data.data.score, data.data.times);
|
||
|
break;
|
||
|
case 'startDrill': // 开始训练游戏
|
||
|
console.log(data.data);
|
||
|
window.gameInfo = data.data;
|
||
|
initBeginCount();
|
||
|
break;
|
||
|
case 'countdown':
|
||
|
onCountdownMessage();
|
||
|
break;
|
||
|
case 'score':
|
||
|
onScoreMessage(data.data.score, data.data.times);
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ws 关闭
|
||
|
function onClose(event) {
|
||
|
connected = false;
|
||
|
if (sendHeartTimer) clearInterval(sendHeartTimer);
|
||
|
// console.warn('close:', connected, new Date().toLocaleString());
|
||
|
if (!event || event.code !== 1005) {
|
||
|
socket.close();
|
||
|
}
|
||
|
|
||
|
setTimeout(() => {
|
||
|
// connected 在这里的作用是:
|
||
|
// 在发生重连 但是还没连上之前 不要再次重连
|
||
|
initSocket();
|
||
|
}, 300);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 发送消息
|
||
|
* @param data
|
||
|
*/
|
||
|
function send(data) {
|
||
|
if (connected) {
|
||
|
if (ws.readyState === 1) {
|
||
|
ws.send(JSON.stringify({ toDomain: 'Server', data: JSON.stringify(data) }));
|
||
|
}
|
||
|
} else {
|
||
|
socketMsgQueue.push(data);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// 认证消息
|
||
|
function auth() {
|
||
|
// TODO: userId拿父框架传递过来的
|
||
|
const data = { type: 'Auth', data: { userId: '1399952569681448962' } };
|
||
|
send(data);
|
||
|
}
|
||
|
|
||
|
// 心跳检测
|
||
|
function sendHeart() {
|
||
|
if (sendHeartTimer) clearInterval(sendHeartTimer);
|
||
|
sendHeartTimer = setInterval(() => {
|
||
|
if (Date.now() - prevTimestamp >= 15000) {
|
||
|
send({ type: 'Ping' });
|
||
|
|
||
|
if (Date.now() - prevTimestamp > 20000) {
|
||
|
// console.warn('手动断开');
|
||
|
ws.close();
|
||
|
}
|
||
|
}
|
||
|
}, 5000);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 处理auth认证返回的ChannelStatus消息
|
||
|
* @param {object} data 消息内容对象
|
||
|
*/
|
||
|
function handleAuthMessage(data) {
|
||
|
if (data.data.authed) {
|
||
|
// 认证成功
|
||
|
sendHeart();
|
||
|
} else {
|
||
|
console.error('消息系统认证失败');
|
||
|
// 清除掉本地无用的token
|
||
|
ws = null;
|
||
|
}
|
||
|
}
|