许多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%确定在设置适当的处理程序之后确保连接?
答案 0 :(得分:0)
https://www.w3.org/TR/2011/WD-websockets-20110419/#the-websocket-interface
我相信下面的数字6可以回答你的问题。
当调用WebSocket()构造函数时,UA必须运行以下步骤:
如果port是用户代理配置为阻止访问的端口,则抛出SECURITY_ERR异常。 (用户代理通常会阻止访问SMTP等知名端口。) 不应阻止对端口80和443的访问,包括安全性为假但端口为443或安全性为真但端口为80的不太可能的情况。
如果没有协议,请让协议为空数组。 否则,如果存在协议和字符串,则让协议成为仅包含该字符串的数组。
如果协议中的任何值出现多次,或者包含Unicode代码点小于U + 0021或大于U + 007E的字符(即空格字符或任何不可打印ASCII字符的字符) ,然后抛出SYNTAX_ERR异常并中止这些步骤。
<强>更新强>
https://html.spec.whatwg.org/multipage/web-sockets.html#feedback-from-the-protocol
建立WebSocket连接后,用户代理必须将任务排队以运行以下步骤:
将readyState属性的值更改为OPEN(1)。
如果不是空值,请将extensions属性的值更改为正在使用的扩展名。 [WSP]
如果不是空值,则将协议属性的值更改为正在使用的子协议。 [WSP]
在WebSocket对象上触发名为open的事件。
请注意
由于上述算法作为任务排队,因此在建立的WebSocket连接和为开放事件设置事件监听器的脚本之间没有竞争条件。