JavaScript WebSockets API的机制

时间:2013-01-16 20:21:30

标签: javascript asynchronous websocket

我一直在努力了解用于打开websocket的一些代码:

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

我的问题是握手是如何开始的?如果它是在WebSocket构造函数中启动的话,那么如果onopen没有被设置那么它是如何调用的呢?如果WebSocket构造函数创建了一个执行握手的线程,那么在握手结束之前是否必须足够快地定义onopen?如果是这样,那听起来有点危险,因为如果JS虚拟机速度变慢,则可以在定义onopen之前完成握手,这意味着事件不会被处理。或者设置onopen功能会触发握手吗?

有人可以向我解释一下API的机制吗?

2 个答案:

答案 0 :(得分:9)

在执行当前(同步)代码结束之前,它不会查找onopen函数。那是因为连接(因此调用onopen回调)是异步的。 考虑:

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

while循环永远不会结束,但你可能会怀疑它会在一秒后结束。

如果通过执行耗时(但同步)的代码来延迟onopen函数的初始化,则它并不危险。另一方面,如果你setTimeout初始化onopen,则无法保证在WebSockets连接准备就绪时是否已定义,因为您无法确定首先执行哪个回调。

如果你在C ++中做同样的事情,你会使用线程。在JavaScript中,回调机制不是基于线程的;它只是表现为线程(参见上面的无尽循环)。

  

单个线程一次执行一个代码单元和其他代码单元   排队,直到当前代码单元完成执行

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

重要的是要理解,即使你{1}}为1s的东西,它也可能在一秒后执行 - 如果线程忙,它可能永远不会被执行。

因此,如果您启动WebSocket连接并运行类似于上面的循环,但等待连接准备就绪,它可能永远不会结束。

对于不熟悉JS的程序员来说,这种行为可能看起来很奇怪。因此,为了便于阅读,我会在可能的情况下同时或在需要它们的函数之后立即定义回调。

如果要显式使用线程和并发执行,请阅读有关Web Workers

的更多信息

<强>参考:

答案 1 :(得分:1)

您不需要任何setTimeout函数。我正在使用一个库,我的代码看起来像这样:

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

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

这给了我一个关于websockets以及如何在Javascript中实现客户端的洞察力:https://github.com/wandenberg/nginx-push-stream-module/blob/master/misc/js/pushstream.js

还有服务器:https://github.com/wandenberg/nginx-push-stream-module/

有很好的记录,我希望它有所帮助:)