You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

浏览器JS WebSocket仅首次发信成功 按键触发发送异常排查

问题原因

你的代码存在两个核心逻辑错误,直接导致回调不执行、消息发不出去:

  • 对WebSocket.onopen的触发时机理解完全错误:这个事件仅在WebSocket连接从「正在连接」切换到「连接成功」的瞬间触发1次,连接保持打开的整个生命周期里不会重复触发。你初始化WebSocket时第一次绑定的onopen已经在连接建立时触发过、发完"L"了,后续你在按键事件里反复给websocket.onopen赋新的回调函数,根本等不到事件触发——连接早就处于打开状态了,不会再抛open事件,你写的这些回调自然永远不会执行。
  • 页面跳转逻辑会直接销毁当前上下文:就算你写的回调能触发,你把window.location.href = 'xxx'写在websocket.send()前面,浏览器执行到跳转语句时会立刻卸载当前页面,销毁所有JS运行上下文、断开WebSocket连接,后面的send根本没机会执行;就算把send挪到跳转前面,也可能因为页面卸载太快导致消息没发完就断连。

另外你写的按键状态跟踪逻辑也有bug:只在keydown事件里把对应键的状态设为true,没在keyup事件里重置为false,按过一次A/B之后,对应状态永远为真,后续按任意键都会误触发分支。

修正方案
  1. 不要在按键事件里重绑onopen回调,发送消息前先判断WebSocket连接状态,连接处于打开状态时直接调用send()即可。
  2. 调整执行顺序:先发送WebSocket消息,确认消息发出去之后再执行页面跳转,避免页面提前卸载导致消息丢失。
  3. 补上keyup事件的状态重置逻辑,加个重复触发判断,避免按住按键时重复执行逻辑。

修正后的核心JS代码参考:

// 清空localStorage
window.localStorage.clear();

// 初始化WebSocket连接
const url = "ws://192.168.4.1:1337";
const websocket = new WebSocket(url);
// 仅在初始化时绑定一次onopen,处理连接初次建立的逻辑
websocket.onopen = function (event) {
    console.log('websocket is open');
    websocket.send("L");
};
// 可选:加连接错误、关闭日志方便排查问题
websocket.onerror = (e) => console.log('ws connection error', e);
websocket.onclose = () => console.log('ws connection closed');


// 记录按键按下状态
const isKeyPressed = {
    'a': false,
    'b': false,
};

// 按键抬起时重置状态
document.onkeyup = (keyUpEvent) => {
    isKeyPressed[keyUpEvent.key] = false;
};

document.onkeydown = (keyDownEvent) => {
    keyDownEvent.preventDefault();
    // 按住按键重复触发时直接跳过
    if (isKeyPressed[keyDownEvent.key]) return;
    isKeyPressed[keyDownEvent.key] = true;

    if (isKeyPressed['a']) {
        console.log('a has been pressed');
        // 先判断连接是否正常打开
        if (websocket.readyState === WebSocket.OPEN) {
            websocket.send("4G");
            console.log('send 4G success');
            // 消息发完再跳转页面
            window.location.href = '1_1.html';
        } else {
            console.log('ws not connected, send failed');
        }
    }

    if (isKeyPressed['b']) {
        console.log('b has been pressed');
        if (websocket.readyState === WebSocket.OPEN) {
            websocket.send("4R");
            console.log('send 4R success');
            window.location.href = '2_1.html';
        } else {
            console.log('ws not connected, send failed');
        }
    }
};

内容的提问来源于stack exchange,提问作者Pietro Manzella

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 04:48:04