【问题标题】:Why not one method to connect and send in websocket?为什么不是一种在 websocket 中连接和发送的方法?
【发布时间】:2016-12-05 17:47:30
【问题描述】:

我是新的 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 按钮并将信息发送到 Spring Websocket 示例中给出的 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>

【问题讨论】:

    标签: javascript spring websocket spring-websocket java-websocket


    【解决方案1】:

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

    您应该在stompClient.connect() 回调中调用sendName(),以确保在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);
            });
        });
    }
    

    【讨论】:

    • @OlegKurbatov 这是我过去 2 天和 1/2 天一直在寻找的东西,非常感谢,我犯了同样的错误
    • @OlegKurbatov 您可以为here 发布答案,我会接受的
    【解决方案2】:

    不熟悉 Stomp(所以只是一个疯狂的猜测):实际的 stompClient.connect 调用将回调作为第二个参数。这表明这是异步运行的。然后您尝试使用连接失败,因为它是在实际建立连接之前执行的。尝试将调用放入连接函数的回调时会发生什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-12
      • 2013-01-28
      • 1970-01-01
      • 1970-01-01
      • 2012-04-10
      • 2012-03-25
      • 2014-03-18
      • 1970-01-01
      相关资源
      最近更新 更多