2017-09-27 56 views
0

很多HTML5的WebSocket示例代碼執行這樣的事情:html5/js 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

https://developer.mozilla.org/en-US/docs/Web/API/WebSocket查看示例 – AthMav

+0

這需要研究實際的WebSocket對象以查看它的行爲方式以及首先調用的方法 – sietse85

+0

@AthMav是的,這就是我正在使用的,但我有點擔心事件處理程序在事件可能已經發生後被分配*的事實。 – RocketNuts

回答

0

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

我相信下面這個數字6回答你的問題。

當調用的WebSocket()構造函數中,UA必須執行這些步驟:

  1. 從URL參數解析一個WebSocket的URL的組成部分,以獲取主機,端口,資源名和安全。如果失敗,則拋出SYNTAX_ERR異常並中止這些步驟。
  2. 如果端口是該用戶代理被配置爲阻止訪問的端口,則拋出一個SECURITY_ERR異常。 (用戶劑通常阻止訪問像SMTP衆所周知的端口。) 訪問端口80和443不應當被阻塞,包括不太可能的情況下,當安全是假的,但端口是443或安全是事實,但端口是80

  3. 如果協議不存在,讓協議爲空數組。 否則,如果協議存在和一個字符串,讓協議代替是包括只是該字符串的數組。

  4. 如果任何在協議中的值的出現不止一次或包含使用Unicode字符代碼點小於U + 0021或大於U + 007E(即空格字符或不是可打印的ASCII字符的任何字符),然後拋出SYNTAX_ERR異常並中止這些步驟。

  5. 讓起源爲調用WebSocket()構造函數的腳本的原點的ASCII序列化,轉換爲ASCII小寫。
  6. 返回一個新的WebSocket對象,並在後臺繼續執行這些步驟(不會阻塞腳本)。
  7. 建立到源主機的端口端口(如果指定了一個)到主機主機的WebSocket連接,標誌是安全的,資源名稱爲資源名稱,協議作爲協議列表(可能爲空)並設置延遲cookie標誌。

UPDATE

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

在建立WebSocket連接,用戶代理必須排入一個任務來執行這些步驟:

  1. 更改的readyState屬性的值打開(1)。

  2. 如果不是空值,則將擴展屬性的值更改爲正在使用的擴展。 [WSP]

  3. 如果不是空值,則將協議屬性的值更改爲使用的子協議。 [WSP]

  4. 在WebSocket對象上觸發一個名爲open的事件。

注意

由於上述算法排隊的任務,如果在建立WebSocket的連接和腳本的開放式事件設置事件偵聽器之間的競爭狀態。

+0

謝謝。看到我的附錄,我添加了一些測試代碼。我想知道這是否違反了協議? (這是在Firefox中測試的,最新版本) – RocketNuts

+0

由於警報,onerror沒有機會獲得「註冊」。這就是爲什麼它沒有開火。如果它是一個console.log,它會顯示出火。 – AthMav

+0

是的,但是我很擔心這一點,顯然它立即開始連接。可以想象,它很可能會失敗*立即*(例如,如果沒有可用的互聯網連接,或者websocket url或domain是錯誤的)。我覺得很奇怪,似乎沒有辦法顯式設置任何事件處理程序**,然後再執行可能會導致這些事件的事情(在這種情況下,嘗試連接)。 – RocketNuts

相關問題