Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The mechanics of the JavaScript WebSockets API

I've been trying to understand some code used to open a websocket:

var ws = new WebSocket('ws://my.domain.com');
ws.onopen = function(event) {
    ...
}

My question is how does the handshaking get started? If it is started in the WebSocket constructor, then how does onopen get called if it isn't set by then? If the WebSocket constructor creates a thread that does the handshaking, then does onopen have to be defined quickly enough before the handshaking is over? If so, that sounds a little dangerous because if the JS virtual machine is slowed the handshaking could be finished before onopen is defined, which means that the event is not handled. Or does setting the onopen function trigger the handshaking?

Could someone explain to me the mechanics of the API please?

like image 240
Cthutu Avatar asked Jan 16 '13 20:01

Cthutu


People also ask

How do JavaScript WebSockets work?

The WebSocket API is an advanced technology that makes it possible to open a two-way interactive communication session between the user's browser and a server. With this API, you can send messages to a server and receive event-driven responses without having to poll the server for a reply.

Does WebSocket use JavaScript?

JavaScript is important to WebSocket only in browsers because the browsers have implemented the WebSocket API (See RFC 6455) in JavaScript. So if you want to access WebSocket from within an HTML5 page, you need to write JavaScript.

What is difference between WebSocket and API?

APIs are the best option for applications where you just need basic CRUD operations and synchronous responses. Also, APIs can be used with both web and mobile applications and service integrations with ease. But, if your web application requires real-time communication with the backend, you should choose WebSockets.


2 Answers

It does not look for onopen function until end of execution of current (synchronous) code. That is because the connection (and thus calling onopen callback) is asynchronous. Consider:

let x = false;
setTimeout(function () {
    x = true
}, 1000);
while(!x){
    console.log('waiting!');
}

The while loop there will never end but you would probably suspect it'd end after one second.

If you delay the initialisation of onopen function by executing time-consuming (but synchronous) code then it is not dangerous. On the other if you setTimeout initialisation of onopen then there's no guarantee whether it's defined or not at the time the WebSockets connection is ready as you can't be sure which callback will be executed first.

If you were doing the same thing in C++ you'd use threads for that. In JavaScript callbacks mechanism is not thread-based; it just behaves thread-like (see the endless while loop above).

Single thread executes one code-unit at a time and other code units are queued until the current code unit is finished executing

source: http://www.slideshare.net/clutchski/writing-asynchronous-javascript-101

It's important to understand that even if you setTimeout something for 1s it might not execute after one second - If the thread is busy it might never get executed.

Thus if you initiate WebSocket connection and run a loop similar to the one above but waiting for the connection to be ready it might never end.

This behaviour might look strange for programmers not familiar with JS. Therefore for readability I define callbacks at the same time or immediately after the functions which need them whenever it's possible.

If you want to explicitly use threads and concurrent execution, read more about Web Workers

Reference:

  • How JavaScript Timers Work
  • Understanding JavaScript timers
like image 189
6 revs Avatar answered Oct 09 '22 04:10

6 revs


You don't need any setTimeout function. I'm using a library for this and my code looks something like this:

var pushstream = new PushStream({
  host: window.location.hostname,
  port: window.location.port,
  modes: "websocket"
});
pushstream.onmessage = _manageEvent;

function _manageEvent(eventMessage) {
  console.log(eventMessage);
}

This gave me a hell of an insight on websockets and how to implement a client in Javascript: https://github.com/wandenberg/nginx-push-stream-module/blob/master/misc/js/pushstream.js

And also the server: https://github.com/wandenberg/nginx-push-stream-module/

It's very well documented I hope it helps :)

like image 35
Ariel Monaco Avatar answered Oct 09 '22 04:10

Ariel Monaco