为什么 JS WebSocket 会卡在 sparkjava 中的 CONNECTING 上?

问题描述

这是我的 websocket 代码

@WebSocket
public class SocketServer {
    BetterLogger logger = new BetterLogger(Main.logger) {{
        loggerName = "socket-server";
    }};
    public static class ConnectionInit {
        String tty;
        String device;
    }

    static class ConnectionopenResponse {
        String tty;
    }

    @OnWebSocketConnect
    public void onConnect(Session user) throws Exception {
        Main.logger.info("Websocket connected!");
    }

    @OnWebSocketClose
    public void onClose(Session user,int statusCode,String reason) {
        Main.logger.info("Websocket disconnected!");
        Main.sessions.closeSession(user);
    }

    @OnWebSocketMessage
    public void onMessage(Session user,String message) {
        Main.logger.info("Recevied websock connection: " + message);
        
        try {
            if (Main.sessions.contains(user)) {
                // treat as raw buffer
                Main.sessions.write(user,message);
            }
            else {
                ConnectionInit heartbeat = Main.gson.fromJson(message,ConnectionInit.class);
                String s = Main.config.getTTY(heartbeat.device + '.' + heartbeat.tty);

                // make sure that the tty exists in config
                if (s == null)
                    user.close(400,"Invalid device/tty!");

                // get UUID
                Main.sessions.newSession(s,user);

                logger.info("created session (" + user + ") with dev " + heartbeat.device + ":" + heartbeat.tty);
                user.getRemote().sendString(Main.gson.toJson(new ConnectionopenResponse() {{
                    tty = s;
                }},ConnectionopenResponse.class));
            }
        }
        catch (SessionException e ) {
            user.close(500,e.getMessage());
        }
        catch (JsonSyntaxException e) {
            user.close(400,e.getMessage());
        }
        catch (IOException e) {
            // wtf
        }
    }

}

我已经在我的 Main 类中正确注册了它,当我尝试使用 websocat 连接到它时,一切似乎都运行良好,我可以发送数据并且一切运行良好。但是,一旦我创建了一个网页,websocket 就永远不会打开:

console.log("ws://" + location.hostname + ":" + location.port + "/device");
const socket = new WebSocket("ws://" + location.hostname + ":" + location.port + "/device");
var term = new Terminal();

term.open(document.getElementById('terminal'));
term.write('Press enter to re-flush buffers\n');

//while(socket.readyState !== 1);
//console.log("connected!");

socket.send("testdata");

term.onData( (data) => {
    console.log(data);
    if (data.charCodeAt(0) == 13)
        socket.send('\n');
    socket.send(data);
});

// Listen for messages
socket.addEventListener('message',function (event) {
    term.write(event.data);
});

现在,代码打印出正确的 URL (ws://localhost:16838/device),但是,它停留在 CONNECTING,并抛出以下错误(我预计这是因为它仍在连接):

Uncaught DOMException: Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.

查看我的服务器日志,我可以看到它确实打印了 Websocket connected!,这甚至没有任何意义。解决我的 JS websocket 客户端卡住的原因有什么帮助吗?

解决方法

事实证明您需要添加 open 事件,否则它实际上不会打开