问题
I am new websocket and refering to the below Spring Websocket tutorial and it is working fine in my system. I am also using stomp.js and sockjs-0.3.4.js.
https://spring.io/guides/gs/messaging-stomp-websocket/
If the html and javascript has two distinct methods like below, it works.
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 }));
}
If I write a single javascript function as given below, it does not work and get the error as Uncaught Error: INVALID_STATE_ERR.
function startAndSend() {
connect();
sendName();
}
I want to know why it is not working. It may be dumb question, please help me in this regard. I provide below the complete html file. Is it always necessary to write html button for connect and send information to websocket as given in the Spring Websocket example ? Is it not possible to onClick of a button, it will connect and send information to websocket ? It seems to be a peculiar for me, I need your help.
<!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>
回答1:
That is because stompClient.connect()
method is asynchronous and when you call sendName()
right after connect()
connection is not established yet.
You are supposed to call sendName()
in stompClient.connect()
callback to be sure that connection is established by the time sendName()
invokes.
For example:
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);
});
});
}
回答2:
Without being familiar with Stomp (so just a wild guess): The actual stompClient.connect call takes a callback as the second argument. This indicates that this runs asynchronous. Your attempt at using the connection then fails because it is executed before the connection has actually been established. Try what happens when you put the call into the callback of the connect function.
来源:https://stackoverflow.com/questions/38685420/why-not-one-method-to-connect-and-send-in-websocket