2012-03-13 541 views
3

我在python中編寫了一個(not-so-)簡單的websocket服務器,它在一個端口上偵聽,執行握手,然後向客戶端發送包含數字的消息序列(間隔一段隨機間隔)。如何知道客戶端使用哪個websocket版本?

我寫了一個javascript客戶端,並在Chrome和Safari下測試它。我發現Chrome和Safari使用不同的WebSocket版本。例如,Chrome使用Sec-WebSocket-Key(並且期望Sec-WebSocket-Accept),而Safari在標題之後發送Sec-WebSocket-Key1,Sec-WebSocket-Key2和一堆8個字節。

我在服務器中實現了一個握手函數,它檢測所需的握手類型並執行它。這個問題解決了。從Chrome或Safari(包括OSX,Windows和IOS5版本)可以正確打開websocket。

但我有另一個問題。顯然,Safari會發送並期望由0x00和0xFF分隔的消息,而Chrome會發送和預計帶框和屏蔽的數據(使用更新版本的websocket規範)。

我想有一臺服務器,它適應客戶的期望。我的問題是,我怎麼能提前告訴數據是否需要發送幀或0x00,0xFF分隔?我想我可以假設,如果握手協議基於Key1和Key2,客戶端是Safari,然後使用0x00 0xFF來分隔數據,而如果它使用Sec-WebSocket-Key,客戶端是Chrome,然後使用框架數據。不過,我對這個解決方案並不滿意,因爲它不是一般的。想法?

回答

3

有已公佈的標準兩者由鉻和其他人使用的Safari(桌面&移動)和RFC 6455使用的hixie-76協議的變體。

您可以使用請求的握手類型來決定客戶端說的協議版本,消息讀取時將存在哪些幀,以及您應該在消息寫入時使用哪些幀。

+0

謝謝你的鏈接。如果我理解正確,沒有「WebSocket-Version」或類似的頭文件,那麼我應該編寫專門的代碼來手動檢測使用的版本,對吧? – JLDiaz 2012-03-13 09:26:04

+1

這是正確的。 (在後來的RFC草案中有一個版本頭文件,但是Chrome和Safari都沒有合適的頭文件)。我有一個簡單的websocket服務器,它使用Sec-WebSocket-Key1頭文件來推斷hixie-76(Safari)和Sec-WebSocket-Key標題來推斷RFC 6455(Chrome)。 – simonc 2012-03-13 09:30:54

+3

這是不正確的。對於任何> = Hybi.10,標題由Chrome,Firefox,WebKit Nightly,IE10發送。Sec-WebSocket-Version。他們確實發送了8個或13個。這個頭文件對於舊的Hixie-76來說並不存在,但是在這個被棄用的版本中仍然只有Safari。 Webkit Nightly擁有RFC6455。 看一下:http://autobahn.ws/testsuite/reports/clients/index.html 點擊不同瀏覽器的案例1.1.1,向下滾動到WebSocket握手。 聲明:我是Autobahn的作者,爲Tavendo工作。 – oberstet 2012-03-13 12:43:35

-1

簡單:只是WebSockets的一個版本。其餘的都是草稿。現在RFC已經出來,你已經正式推薦不要實現其他任何東西。最新版本的Firefox和Chrome都實現了RFC版本,並且它們會自動更新。這些草案將很快停止被客戶使用,因此嘗試實施它們甚至獲得更多的互操作性也沒有意義。

他們不再相關,並添加cruft。任何瀏覽器供應商都不打算繼續支持草案。事實上,Mozilla在未修正其websocket對象之前一直等到規範。同樣,瀏覽器供應商明確表示,爲草稿編寫的任何應用程序都應該是演示版本,而不是生產代碼,並且不會期望他們支持草稿服務器,而不是支持草稿客戶端代碼。

因此,堅持一個規範,並忘記草稿的早期實施。

+2

如果您想在移動設備上運行,則不是真正的選擇。 – kybernetikos 2012-05-22 10:26:57

+1

同意@kybernetikos。在移動瀏覽器推出採用最新協議的版本之前,您需要與當前協議同時支持舊協議。 – dlchambers 2012-08-13 15:31:02

1

要回答你最初的問題,因爲我有同樣的需求,我發現window.WebSocket.CLOSED在最新的實現中等於3,而在舊版本中,它等於2(例如Android本機瀏覽器)。

所以測試我現在做檢測支持最新的WebSocket協議的是:

if('WebSocket' in window 
    &&'function' === typeof window.WebSocket 
    &&3 === window.WebSocket.CLOSED) { 
// hurra ! 
} 

我在Chrome,火狐(它成功)和Android瀏覽器(如果失敗)進行了測試。希望它能幫助那裏的一些人。

相關問題