Почему бы не один способ подключиться и отправить в веб-сокет?

Я новичок в веб-сокете и ссылаюсь на приведенный ниже учебник 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? Разве нельзя по нажатию кнопки подключиться и отправить информацию в веб-сокет? Мне это кажется странным, мне нужна ваша помощь.

<!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>

person Sambit    schedule 31.07.2016    source источник


Ответы (2)


Это связано с тем, что метод 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);
        });
    });
}
person Oleg Kurbatov    schedule 31.07.2016
comment
@OlegKurbatov это то, что я искал последние 2 и 1/2 дня, большое спасибо, я сделал ту же ошибку - person Shantaram Tupe; 30.11.2017
comment
@OlegKurbatov, вы можете опубликовать ответ для здесь, я приму его - person Shantaram Tupe; 02.12.2017

Не будучи знакомым с Stomp (так что просто дикая догадка): фактический вызов stompClient.connect принимает обратный вызов в качестве второго аргумента. Это указывает на то, что это работает асинхронно. Ваша попытка использовать соединение затем терпит неудачу, потому что она выполняется до того, как соединение действительно установлено. Попробуйте, что произойдет, если вы поместите вызов в функцию обратного вызова функции подключения.

person gzost    schedule 31.07.2016