如何每隔5秒切换runOurCode布尔值以触发WebSocket.send代理逻辑
修复方案
现有代码的核心问题
- 两次覆写
WebSocket.prototype.send,第一次的代理逻辑被完全覆盖,无法生效 - 第二个代理的执行逻辑中每次调用
send都会新增一个keypress监听事件,会造成严重内存泄漏 - 此前定时器不生效的根本原因:
runOurCode的判断逻辑仅在WebSocket.send被主动调用时才会执行,若没有触发send的操作,即使修改了变量也不会执行发送[5,77]的逻辑
修正后完整代码
var editingCode; let runOurCode = false; // 合并两次代理逻辑,仅覆写一次send方法 WebSocket.prototype.send = new Proxy(WebSocket.prototype.send, { apply: function(target, scope, args) { // 保留原有解析json、存储editingCode的逻辑,新增异常捕获避免非json消息报错 if (typeof(args[0]) === 'string') { try { let json = JSON.parse(args[0]); if (json[0] === 3) { editingCode = json[1]; } } catch(err) {} } // 保留runOurCode触发特殊消息发送的逻辑 if (runOurCode) { target.apply(scope, [`[5,77]`]); runOurCode = false; } // 执行原有发送逻辑 return target.apply(scope, args); } }) // 按键监听挪到全局,仅绑定一次 document.addEventListener("keypress", e => { if (e.code === "KeyC") { runOurCode = true; // 若需要按键后立刻触发发送,可在此处调用你的业务WebSocket实例的send方法 } }) // 5秒定时触发逻辑 setInterval(() => { runOurCode = true; // 若需要定时后立刻发送,不需要等下一次主动send,可在此处调用你的业务WebSocket实例的send方法,示例: // yourWsInstance.send('') }, 5000)
逻辑说明
定时器每隔5秒会将runOurCode设为true,之后只要有任意一次WebSocket.send调用,就会自动触发[5,77]的发送,发送完成后自动将变量重置为false。如果需要定时触发后立刻执行发送,不需要等待下一次主动send,直接在定时器的回调中调用你的业务WebSocket实例的send方法即可。
内容的提问来源于stack exchange,提问作者2341
相关产品推荐
相关产品推荐

