本文最后更新于138 天前,其中的信息可能已经过时,如有错误请发送邮件到2778680280@qq.com
优化重连逻辑, U 校园ai版本 WS 心跳保活脚本
其实理论上所有刷课网站都可以保活 只需要替换关键参数
为什么要做这个脚本?
让大家有更多时间做自己的事情,不用刷傻逼时长。
核心优化点
1. 降低交互频率,适配单连接限制
把默认的心跳间隔延长到 15 秒,重连延迟调整为 8 秒。既保证连接不会因为超时断开,又避免了短时间内多次请求触发平台的单连接限制,同时也减轻了服务器压力,一举多得。
2. 完善的异常处理与资源清理
- 心跳发送前先校验 WS 连接状态,未连接时跳过发送并给出提示,避免无效报错;
- 连接关闭 / 出错时自动触发重连,但重连前会先清理旧连接和定时器,防止多连接冲突;
- 页面关闭时自动清空所有定时器、关闭 WS 连接,避免内存泄漏。
3. 可视化调试日志
加了带时间戳和状态标识的日志输出(✅成功 /⚠️警告 /❌错误),控制台能清晰看到连接状态、心跳发送结果,排查问题时一目了然,调试模式也可以一键关闭。
4. 灵活的手动控制
脚本暴露了stop()和restart()方法,不想用了可以手动停止,出问题也能一键重启,不用刷新页面重新执行脚本。
核心逻辑拆解
- 初始化连接:启动时先清理旧连接和定时器,创建新的 WS 连接,连接成功后立即发送一次心跳,随后按 15 秒间隔定时发送;
- 心跳包处理:动态替换心跳模板中的时间戳参数,保证每次发送的心跳包唯一且符合平台格式要求;
- 重连机制:连接关闭或创建失败时,8 秒后自动重建连接,全程无需手动干预;
- 资源释放:页面关闭、手动停止时,彻底清理定时器和 WS 连接,避免残留问题。
使用方法
- 直接复制脚本到浏览器控制台执行,自动启动心跳保活;
- 调试模式默认开启,如需关闭日志,将 CONFIG 里的 debug 改为 false 即可;
- 手动控制:执行脚本返回对象的
stop()停止服务,restart()重启服务; - 核心配置(WS 地址、心跳模板)无需修改,适配 U 校园默认格式。
本体
// 🚀 U校园WS心跳最终版(减少重连频率,适配单连接限制)
(function() {
‘use strict’;
// 🚀 U校园WS心跳最终版(减少重连频率,适配单连接限制)+ 防长时间未操作检测
(function() {
'use strict';
// ========== 核心配置(无需修改) ==========
const CONFIG = {
WS_URL: 'wss://umcs.unipus.cn/umcs/?appId=1&openId=6f8cd8e9bd4b4a22aa0d3a085c46db6b&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJvcGVuX2lkIjoiNmY4Y2Q4ZTliZDRiNGEyMmFhMGQzYTA4NWM0NmRiNmIiLCJuYW1lIjoiIiwiZW1haWwiOiIiLCJhZG1pbmlzdHJhdG9yIjpmYWxzZSwiZXhwIjoxNzk2NzM4MTQ0NzA1LCJpc3MiOiJjNGY3NzIwNjNkY2ZhOThlOWM1MCIsImF1ZCI6ImVkeC51bmlwdXMuY24ifQ.se6iYGby6f1sld2Ft-aDm-y-08PdV0ovt1IH983laBs&devId=7e171a7d6b54b6a8c3e04ae9b378412e&EIO=4&transport=websocket',
HEART_TEMPLATE: '42["start",{"client":"pc","module":"6775593db020b63","moduleGroup":"course-v2:8153f185000e57d+nhce_v4_rw_xxt_1+20250618","url":"https://ucontent.unipus.cn/_explorationpc_default/pc.html?cid=1600722671889351088&theme=3264FA&aitutorialId=16805&cloudCurriculaId=238072&source=cloud&courseResourceId=20000860328#/course-v2:8153f185000e57d+nhce_v4_rw_xxt_1+20250618/courseware/6775593da000b63/6775593db000b63/6775593db010b63/6775593db020b63","tag1":"6775593da000b63","tag2":"6775593db000b63","tag3":"{\"microBlock\":\"6775593da000b63/6775593db000b63\",\"version\":\"1\",\"source\":\"ucontent\"}","timer":TIMER_PLACEHOLDER}]',
heartInterval: 15000, // 心跳间隔15秒
reconnectDelay: 8000, // 重连间隔8秒
userActiveInterval: 60000, // 模拟用户操作间隔(1分钟,可根据检测阈值调整)
debug: true
};
// ========== 全局变量 ==========
let ws = null;
let heartTimer = null;
let reconnectTimer = null;
let userActiveTimer = null; // 模拟用户操作定时器
// ========== 工具函数 ==========
const log = (type, message) => {
if (!CONFIG.debug) return;
const time = new Date().toLocaleTimeString();
const prefixes = { success: '✅', warn: '⚠️', error: '❌', info: 'ℹ️' };
console.log(`${prefixes[type] || 'ℹ️'} [${time}] ${message}`);
};
const clearAllTimers = () => {
if (heartTimer) clearInterval(heartTimer);
if (reconnectTimer) clearTimeout(reconnectTimer);
if (userActiveTimer) clearInterval(userActiveTimer); // 清理用户操作定时器
heartTimer = null;
reconnectTimer = null;
userActiveTimer = null;
};
// ========== 防长时间未操作核心函数 ==========
const simulateUserActivity = () => {
try {
// 1. 模拟鼠标随机移动(避免固定位置被检测)
const randomX = Math.floor(Math.random() * window.innerWidth);
const randomY = Math.floor(Math.random() * window.innerHeight);
const mouseMoveEvent = new MouseEvent('mousemove', {
clientX: randomX,
clientY: randomY,
bubbles: true, // 事件冒泡,模拟真实操作
cancelable: true
});
document.dispatchEvent(mouseMoveEvent);
// 2. 模拟轻微滚动(可选,增加真实性)
if (Math.random() > 0.5) { // 50%概率执行,避免规律
const scrollDir = Math.random() > 0.5 ? 10 : -10; // 随机上下滚动
window.scrollBy(0, scrollDir);
}
// 3. 模拟点击页面空白处(可选)
if (Math.random() > 0.7) { // 30%概率执行
const clickEvent = new MouseEvent('click', {
clientX: randomX,
clientY: randomY,
bubbles: true,
cancelable: true
});
document.body.dispatchEvent(clickEvent);
}
log('success', `模拟用户操作成功 🖱️ (鼠标位置: ${randomX}, ${randomY})`);
} catch (e) {
log('error', `模拟用户操作失败: ${e.message}`);
}
};
// ========== WS心跳核心逻辑 ==========
const sendHeartbeat = () => {
if (!ws || ws.readyState !== WebSocket.OPEN) {
log('warn', 'WS未连接,跳过本次心跳');
return;
}
try {
const heartMsg = CONFIG.HEART_TEMPLATE.replace('TIMER_PLACEHOLDER', Date.now());
ws.send(heartMsg);
log('success', '心跳包发送成功 ✨');
} catch (e) {
log('error', `心跳发送失败: ${e.message}`);
}
};
const createWS = () => {
// 清理旧连接和定时器
clearAllTimers();
if (ws) { try { ws.close(); } catch (e) {} ws = null; }
try {
ws = new WebSocket(CONFIG.WS_URL);
log('info', '正在建立WS连接...');
ws.onopen = () => {
log('success', 'WS连接建立成功!');
sendHeartbeat(); // 立即发一次心跳
heartTimer = setInterval(sendHeartbeat, CONFIG.heartInterval);
// 启动模拟用户操作定时器
userActiveTimer = setInterval(simulateUserActivity, CONFIG.userActiveInterval);
simulateUserActivity(); // 立即执行一次,避免初始等待
};
ws.onmessage = (event) => {
if (event.data.includes('ok')) log('success', `服务器响应正常: ${event.data.substring(0, 40)}...`);
};
ws.onclose = () => {
log('warn', `WS连接关闭,${CONFIG.reconnectDelay/1000}秒后自动重连`);
clearAllTimers();
reconnectTimer = setTimeout(createWS, CONFIG.reconnectDelay);
};
ws.onerror = (error) => {
log('error', `WS错误: ${error.message || '未知错误'}`);
};
} catch (e) {
log('error', `创建WS失败: ${e.message}`);
reconnectTimer = setTimeout(createWS, CONFIG.reconnectDelay);
}
};
// 页面关闭清理
window.addEventListener('beforeunload', () => {
clearAllTimers();
if (ws) ws.close();
log('info', '页面关闭,停止心跳和用户操作模拟服务');
});
// 启动
createWS();
// 暴露控制方法
return {
stop: () => {
clearAllTimers();
if (ws) ws.close();
log('info', '心跳和用户操作模拟服务已手动停止');
},
restart: createWS
};
})();
})();









