1

I'm still new to Javascript and I'm trying to work with WebSockets. I have a working skeleton of an application, though it still has issues I need to resolve.

How can I signal to the rest of the application that the web socket is ready for use?

socket = new WebSocket( 'wss://' + window.location.host + '/ws/manager/' );
while (socket.readyState != 1){
    // wait loop
}

When the socket is created it returns immediately, but is not yet ready for communication. My first thought was that I just loop while checking the status, which is my current solution, but that just burns CPU and would make the application unresponsive. Introducing a delay would resolve some responsiveness, but that has its own issues as shown here: What is the JavaScript version of sleep()? for example . I also understand that looping to wait is a no no.

The other solution I saw was to use setTimeout() and a callback to continue execution, but I feel like that would be very disruptive to the code reading and writing, and possibly still not entirely solve the issue in a better way.

This will be a one page application, and the server communication will be done almost entirely with web sockets due to the sheer number of connections that would be required with ajax or conventional HTTP. In general, I don't really mind that the app would become unresponsive, since without the web socket it would be pretty useless anyway.

Brian
  • 642
  • 7
  • 18
  • make the function async and add await to the socket? https://javascript.info/async-await – JensW May 07 '19 at 13:15
  • That's where I ran into trouble though. If I make the function async, and use await, then that just moves the problem to the next level, doesn't it? Calling the async function to reconnect will return immediately and I still don't know when the socket connects. – Brian May 07 '19 at 13:16
  • @Dementic, thanks for pointing that out. I think I XY'd myself into a deep hole. That question and the answers provide the feedback I was looking for. – Brian May 07 '19 at 13:21
  • javascript (in browser) is usually a single thread business. So "waiting" doesn't make much sense (waiting for what?). Hard to tell from your question if anything is running in the background. If not, I am not sure what you are trying to achieve (a listener on a socket won't work anyway until the socket is ready). – LongChalk May 07 '19 at 13:22
  • @LongChalk I'm trying to address the situation where the application just starts (nothing running) and the application experiences a disconnect (stuff is running) so both scenarios need a solution. "Waiting" is until the application can actually do something useful over the WebSocket – Brian May 07 '19 at 13:24

1 Answers1

3

You could listen for the "onopen" event on the WebSocket like this:

socket = new WebSocket('wss://' + window.location.host + '/ws/manager/');
socket.addEventListener('open', function (event) {
  socket.send('Hello socket server!');
  // Do more stuff with your socket
})

That way, your application will be responsive while the WebSocket is loading and you don't waste any CPU.

For more information about the WebSocket API, check here: https://developer.mozilla.org/en-US/docs/Web/API/WebSocket

Hope this helps!

Wouter Raateland
  • 1,007
  • 8
  • 13
  • While my question is a duplicate and I accept that, I still don't understand how this would work when you don't want to wait indefinitely for the listener to fire. How would you bound this with a timeout mechanism? – Brian May 07 '19 at 13:51
  • 1
    That is an entirely different question. I'd recommend you to look further into promises or race conditions therefor: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race Example code implementing a timeout mechanism: `(new Promise((resolve, reject) => {socket.addEventListener('open', resolve);setTimeout(reject, 1000)})).then(() => alert('connected')).catch(() => alert('timed out...'))` – Wouter Raateland May 07 '19 at 15:29