Reputation: 4273
I have the following html/javascript code that uses websockets to communicate with a server. It seems like I can only send(message)
only inside the onmessage()
and onopen()
functions. How can I send data outside of those functions ?
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript">
function WebSocketTest() {
if ("WebSocket" in window) {
var ws = new WebSocket("ws://localhost:57252/");
ws.onopen = function () {
ws.send("Hi, from the client."); // this works
alert("Connection opened...");
};
ws.onmessage = function (event) {
alert("Message received..." + event.data);
};
ws.onclose = function () {
alert("Connection closed...");
};
ws.send("Hi, from the client."); // doesn't work
ws.send("Hi, from the client."); // doesn't work
}
}
</script>
</head>
<body>
<div id="sse">
<a href="javascript:WebSocketTest()">Run WebSocket</a>
</div>
</body>
</html>
Upvotes: 1
Views: 34815
Reputation: 141
This is the html file of Sanic webserver websocket demo.
<!DOCTYPE html>
<html>
<head>
<title>WebSocket demo</title>
</head>
<body>
<script>
var ws = new WebSocket('ws://' + document.domain + ':' + location.port + '/feed'),
messages = document.createElement('ul');
ws.onmessage = function (event) {
var messages = document.getElementsByTagName('ul')[0],
message = document.createElement('li'),
content = document.createTextNode('Received: ' + event.data);
message.appendChild(content);
messages.appendChild(message);
};
document.body.appendChild(messages);
window.setInterval(function() {
data = 'bye!'
ws.send(data);
var messages = document.getElementsByTagName('ul')[0],
message = document.createElement('li'),
content = document.createTextNode('Sent: ' + data);
message.appendChild(content);
messages.appendChild(message);
}, 1000);
</script>
</body>
Upvotes: 0
Reputation: 17457
You are probably experiencing a race condition where you try to perform a send
command even though the socket may not have been opened yet. There's an important note on the MDN that describes this behavior:
As establishing a connection is asynchronous and prone to failure there is no guarantee that calling the send() method immediately after creating a WebSocket object will be successful.
You, essentially, are calling the send method immediately after creating a WebSocket.
If you move that logic to a function and call that function when you know the connection has been open, you might be fine. For example, try moving the code into a timeout or another function that can be manually triggered after you know the socket connection has been established:
function sendMyMessages() {
ws.send("Hi, from the client.");
ws.send("Hi, from the client.");
}
<button onclick="sendMyMessages()">Test</button>
Upvotes: 4
Reputation: 2576
Because onopen
is an asynchronous event.
It's similar to doing this:
var value;
$.ajax({
url: '/post/data',
success: function(response) {
value = response;
}
});
alert(value);
What do we get in the alert? undefined
.
The websocket works in a similar manner, you cannot send
until the connection has finished opening. It opens asynchronously. Therefore, anytime you try to use send
, you must ensure that the connection is already open. Right now, you are trying to synchronously use those send
calls, before the connection is actually open.
Upvotes: 2