html5 / js websocket:在连接后设置事件处理程序*?

时间:2017-09-27 14:26:17

标签: javascript html5 events websocket event-handling

许多HTML5 websocket示例代码都是这样的:

websocket = new WebSocket('ws://example.com');
websocket.onopen = MyOpenHandler;
websocket.onerror = MyErrorHandler;

当然,有意在连接时调用MyOpenHandler,或者如果连接失败则调用MyErrorHandler

确切地何时发生实际连接并且上述事件处理方法保证能够正常工作,即使连接发生或失败立即

我的意思是,这样的方法不会更有意义:

websocket = new WebSocket;
websocket.onopen = MyOpenEventHandler;
websocket.onerror = MyErrorHandler;
websocket.connect('ws://example.com');

即。在事件处理程序设置完成后连接,100%确定在适当时调用它们。

或者我只是在这里偏执,并且参考实现(最顶层的例子)实际上是正确的吗?

附录

我使用以下代码进行了一些额外的测试:

var websocket = new WebSocket("ws://localhost:8000"); // this connection will fail
alert("Created the websocket, now let's set the event handler");
websocket.onerror = function(e) { alert("Could not connect") }

这失败了,"无法连接"警报不会出现。但是,如果我删除了之前的警报(第2行的警报),它确实如此。

这有点让我担心。显然,在我有机会设置onerror事件处理程序之前,连接可能已经失败,因此处理程序永远不会被调用。我如何能够100%确定在设置适当的处理程序之后确保连接

1 个答案:

答案 0 :(得分:0)

https://www.w3.org/TR/2011/WD-websockets-20110419/#the-websocket-interface

我相信下面的数字6可以回答你的问题。

当调用WebSocket()构造函数时,UA必须运行以下步骤:

  1. 从url参数中解析WebSocket URL的组件,以获取主机,端口,资源名称和安全性。如果失败,抛出SYNTAX_ERR异常并中止这些步骤。
  2. 如果port是用户代理配置为阻止访问的端口,则抛出SECURITY_ERR异常。 (用户代理通常会阻止访问SMTP等知名端口。) 不应阻止对端口80和443的访问,包括安全性为假但端口为443或安全性为真但端口为80的不太可能的情况。

  3. 如果没有协议,请让协议为空数组。 否则,如果存在协议和字符串,则让协议成为仅包含该字符串的数组。

  4. 如果协议中的任何值出现多次,或者包含Unicode代码点小于U + 0021或大于U + 007E的字符(即空格字符或任何不可打印ASCII字符的字符) ,然后抛出SYNTAX_ERR异常并中止这些步骤。

  5. 让origin成为调用WebSocket()构造函数的脚本原点的ASCII序列化,转换为ASCII小写。
  6. 返回一个新的WebSocket对象,并在后台继续执行这些步骤(不阻止脚本)。
  7. 建立与主机主机的WebSocket连接,在端口上(如果已指定),来自源,标志为secure,资源名称为资源名称,协议为(可能为空)协议列表,并设置延迟cookie标志。
  8. <强>更新

    https://html.spec.whatwg.org/multipage/web-sockets.html#feedback-from-the-protocol

    建立WebSocket连接后,用户代理必须将任务排队以运行以下步骤:

    1. 将readyState属性的值更改为OPEN(1)。

    2. 如果不是空值,请将extensions属性的值更改为正在使用的扩展名。 [WSP]

    3. 如果不是空值,则将协议属性的值更改为正在使用的子协议。 [WSP]

    4. 在WebSocket对象上触发名为open的事件。

    5. 请注意

      由于上述算法作为任务排队,因此在建立的WebSocket连接和为开放事件设置事件监听器的脚本之间没有竞争条件。