javascript - 为什么不是一种在 websocket 中连接和发送的方法?

标签 javascript spring websocket spring-websocket java-websocket

我是新的 websocket,引用了下面的 Spring Websocket 教程,它在我的系统中运行良好。我也在使用 stomp.js 和 sockjs-0.3.4.js。

https://spring.io/guides/gs/messaging-stomp-websocket/

如果 html 和 javascript 有如下两个不同的方法,它就可以工作。

function connect() {
    var socket = new SockJS('/app/hello');
    stompClient = Stomp.over(socket);            
    stompClient.connect({}, function(frame) {
        setConnected(true);
        console.log('Connected: ' + frame);
        stompClient.subscribe('/topic/greetings', function(greeting) {
            //showGreeting(greeting);
            showGreeting(JSON.parse(greeting.body).content);
        });
    });
}

function sendName() {
    var name = document.getElementById('name').value;
    stompClient.send("/app/hello", {}, JSON.stringify({ 'name': name }));
}

如果我按照下面给出的方式编写单个 javascript 函数,它就无法工作,并会收到Uncaught Error: INVALID_STATE_ERR 错误。

function startAndSend() {
            connect();
            sendName();
        }

我想知道为什么它不起作用。这可能是个愚蠢的问题,请在这方面帮助我。我在下面提供了完整的 html 文件。是否总是需要编写 html 按钮来连接并将信息发送到 websocket,如 Spring Websocket 示例中给出的那样?是否无法单击按钮,它会连接并向 websocket 发送信息?这对我来说似乎很奇怪,我需要你的帮助。

<!DOCTYPE html>
<html>
<head>
<title>Hello WebSocket</title>
<script src="sockjs-0.3.4.js"></script>
<script src="stomp.js"></script>
<script type="text/javascript">
        var stompClient = null;

        function setConnected(connected) {
            document.getElementById('response').innerHTML = '';
        }

        function connect() {
            var socket = new SockJS('/app/hello');
            stompClient = Stomp.over(socket);            
            stompClient.connect({}, function(frame) {
                setConnected(true);
                console.log('Connected: ' + frame);
                stompClient.subscribe('/topic/greetings', function(greeting) {
                    //showGreeting(greeting);
                    showGreeting(JSON.parse(greeting.body).content);
                });
            });
        }

        function disconnect() {
            if (stompClient != null) {
                stompClient.disconnect();
            }
            setConnected(false);
            console.log("Disconnected");
        }

        function sendName() {
            var name = document.getElementById('name').value;
            stompClient.send("/app/hello", {}, JSON.stringify({ 'name': name }));
        }

        function showGreeting(message) {
            var response = document.getElementById('response');
            var p = document.createElement('p');
            p.style.wordWrap = 'break-word';
            console.log(message);
            p.appendChild(document.createTextNode(message));
            response.appendChild(p);
        }


        //Does not work
        function startAndSend() {
            connect();
            sendName();
        }
    </script>

</head>
<body>
    <noscript>
        <h2 style="color: #ff0000">Seems your browser doesn't support
            Javascript! Websocket relies on Javascript being enabled. Please
            enable Javascript and reload this page!</h2>
    </noscript>
    <div>
        Stomp Over Websocket using Spring
        <div>
            <button id="connect" onclick="connect();">Connect</button>
            <button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button>
            <button id="check" onclick="startAndSend();">StartAndSend</button>
        </div>
        <div id="conversationDiv">
            <label>What is your name?</label><input type="text" id="name" />
            <button id="sendName" onclick="sendName();">Send</button>
            <p id="response"></p>
        </div>

    </div>
</body>
</html>

最佳答案

那是因为stompClient.connect()方法是异步的,当您调用 sendName() 时在connect()之后尚未建立连接。

你应该调用sendName()stompClient.connect()回调以确保在 sendName() 之前建立连接调用。

例如:

function connect() {
    var socket = new SockJS('/app/hello');
    stompClient = Stomp.over(socket);            
    stompClient.connect({}, function(frame) {
        setConnected(true);
        sendName();
        console.log('Connected: ' + frame);
        stompClient.subscribe('/topic/greetings', function(greeting) {
            //showGreeting(greeting);
            showGreeting(JSON.parse(greeting.body).content);
        });
    });
}

关于javascript - 为什么不是一种在 websocket 中连接和发送的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38685420/

相关文章:

javascript - WEBRTC 带 socket 的开关量输入设备

javascript - 模拟由 react 钩子(Hook)返回的函数

javascript - 无法在 ng-click 函数上获取 ng-bind-html 下拉值

javascript - 一些常见的 JavaScript 问题

python - aiohttp - 如何查看 websocket 消息缓冲区?

javascript - 端口 8888 上的 Socket.io 和端口 80 上的网络服务器 - 无法将两者结合起来

javascript - 使 jqGrid 在 Web 浏览器上响应的方法

java - Spring Boot 过滤器始终映射到/*

java - Spring mvc - 无法打开 ServletContext 资源/WEB-INF/dispatcher-servlet.xml

java - 如何将名称生成器添加到上下文 :component-scan in annotation form?