




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
HTML5WebSocket
權(quán)威指南
目錄
第1章HTML5WebSocket簡介
1.1HTML5是什么
1.2HTML5連接性
1.3舊的HTTP架構(gòu)概覽
1.4WebSocket入門
1.5為什么需要WebSocke:
1.6WebSocket和RFC6455
1.7WebSocket的世界
1.8WebSocket的選擇
1.9相關(guān)技術(shù)
1.10小結(jié)
第2章WebSocketAPI
2.1WebSocketAPI概覽
2.2WebSocketAPI入門
2.3全部組合起來
2.4檢杳WebSocket支持
2.5在WebSocket中使用HTML5媒體
2.6小結(jié)
第3章WebSocket協(xié)議
3.1WebSocket切,議之前
3.2WebSocket協(xié),議簡介
3.3WebSocket協(xié)議
3.4川Node.is編寫JavaScriptWebSocket服務(wù)器
3.5小結(jié)
第4章用XMPP構(gòu)建WebSocket上的即時消息和聊天
4.1分層協(xié)議
4.2XMPP:XML的滸i化
4.3通過WebSocket構(gòu)建聊天和即時消息應(yīng)用程序
4.4建議的擴展
4.5小結(jié)
第5章用STOMP通過WebSocket傳遞消息
5.1發(fā)布發(fā)丁閱模式概覽
5.2STOMP簡介
5.3Web洎息傳遞入門
5.4構(gòu)建STOMP/WS應(yīng)用程序
5.5建議的擴展
5.6Web消息傳遞的未來
5.7小結(jié)
第6章用遠(yuǎn)程幀緩沖協(xié)議實現(xiàn)VNC
6.1VNC概述
6.2構(gòu)建WcbSocket上的tNC客戶端
6.3改進應(yīng)用程序
64小結(jié)
第7章WebSocket安全性
7.1WebSocket安全性概述
7.2WebSocket安全特性
7.3用TLS加強WebSocket安全性
7.4驗證
7.5應(yīng)用級安全性
7.6小結(jié)
第8章部署的考慮
8.1WebSocket應(yīng)用程序部署概述
8.2WebSocket模擬和備用手段
8.3代理和其他網(wǎng)絡(luò)中介
8.4WebSocketping刑Ipong
8.5WebSocket緩沖和流,量控制
8.6的討空
8.7容量規(guī)劃
8.8套接套限制
8.9WebSocket應(yīng)用程序部署檢查列表
8.10小結(jié)
附錄A檢查WebSocket流量
A.1川GoogleChrome開發(fā)者工具進行WebSocket幀檢杳
A.2GoogleChromeNetworkInternals
A.3用Wireshark分析網(wǎng)絡(luò)封包
A.4小結(jié)
附錄BWebSocket資源
B.1使用虛擬機
B.2WebSocket服務(wù)器
第1章HTML5WebSocket簡介
1.1HTML5是什么
本書是為所有想要學(xué)習(xí)如何構(gòu)建實時Web應(yīng)用程序的人而寫的。你可能會對自己說:“我
已經(jīng)這樣做了!”或者問:“這到底是什么意思?”讓我們來澄清一下:本書將說明如何使
用革命性和廣受支持的新型開放行業(yè)標(biāo)準(zhǔn)技術(shù)一WebSocket來構(gòu)建真正的實時Web應(yīng)用
程序。這種技術(shù)能夠在你的客戶端應(yīng)用程序和Web上的遠(yuǎn)程服務(wù)器之間實現(xiàn)全雙工的雙
問通信一不需要插件!
仍然不得要領(lǐng)嗎?幾年以前我們也是這樣,當(dāng)時我們還沒有開始使用HTML5WebSocketo
在這本指南中,我們將解釋你需要知道的WebSocket相關(guān)知識,以及在今天考慮使用
WebSocket的原因。我們將告訴你如何在Web應(yīng)用程序中實現(xiàn)一個WebSocket客戶端,
創(chuàng)建自己的WebSocket服務(wù)器,用WebSocket和更高級協(xié)議(如XMPP利STOMP)協(xié)
同工作,加強客戶端與服務(wù)器之間的通信安全性,以及部署基于WebSocket的應(yīng)用程序。
最后,我們將解釋,為什么你應(yīng)該考慮現(xiàn)在就開始使用WebSocket。
首先,我們來解釋"HTML5WebSocket"中的"HTML5”部分。如果你已經(jīng)是HTML5專?家,
比如說閱讀過《ProHTML5Programming》,并旦己經(jīng)開發(fā)了現(xiàn)代化的響應(yīng)式Web應(yīng)用
程序,可以跳過本節(jié)繼續(xù)閱讀后面的章節(jié)。但是,如果你是HTML5新手,下面的簡單介
紹適合你。
HTML最初用于在Internet上共享的靜態(tài)、基于文本的文檔。隨著時間的推移,Web用
戶和設(shè)計師希望HTML文檔更有交互性,他們開始添加表單功能和早期的“門戶”類功能,
以改進文檔?,F(xiàn)在,這些靜態(tài)的文檔集合(即網(wǎng)站)更像Web應(yīng)用程序,根據(jù)富客戶/
服務(wù)器的桌面應(yīng)用程序原則構(gòu)建。這些Web應(yīng)用程序可用于幾乎所有設(shè)備:筆記本電腦、
智能手機、平板電腦一所有上網(wǎng)設(shè)備。
HTML5用于使富Web應(yīng)用程序的開發(fā)更加簡單、更加自然、更加符合邏輯,開發(fā)人員
可以設(shè)計和構(gòu)建一次,在任何地方部署。HTML5提供了Web應(yīng)用程序的易用性,因為
它不需要插件。通過HTML5,你現(xiàn)在可以使用這樣的語義標(biāo)記語言來代替。多媒體也更
容易編碼,可以用。
1.2HTML5連接性
HTML5連接性領(lǐng)域包括WebSocket、服務(wù)器發(fā)送事件和跨文檔消息傳遞(Cross-
DocumentMessaging)等技術(shù).這些包含在HTML5規(guī)范中的API有助于簡化瀏覽器所受
限制使應(yīng)用程序開發(fā)人員無法創(chuàng)建所需豐富功能,或者Web應(yīng)用程序開發(fā)過于復(fù)雜的情
況。HTML5中的跨文檔消息傳遞就是這種簡化的一個例子。
在HTML5之前,瀏覽器窗口和框架之間的通信由于安全的原因而受到限制。然而,隨著
Web應(yīng)用程序開始組合不同網(wǎng)站中的內(nèi)容和應(yīng)用程序,這些應(yīng)用程序的相互通信變得必
不可少。為了解決這個問題,標(biāo)準(zhǔn)組織和主要瀏覽器供應(yīng)商同意支持跨文檔消息傳遞,后
者能夠確保在瀏覽器窗口、選項卡(tab)和iFrame之間跨源通信的安全??缥臋n消息傳
遞定義了postMessageAPI,作為發(fā)送和接收消息的標(biāo)準(zhǔn)手段。利用來自不同主機和域的
內(nèi)容、在瀏覽器內(nèi)部通信的用例有許多,例如地圖、聊天和社會化網(wǎng)絡(luò)??缥臋n消息傳遞
提供了不同JavaScript上下文之間的異步消息傳遞。
跨文檔消息傳遞的HTML5規(guī)范還通過引入源(origin)的概念,澄清并提升了域安全性,
這一概念由方案(scheme)、主機(host)和端口(port)來定義。根本上,兩個URI
當(dāng)且僅當(dāng)有相同的方案、主機和端口時才被認(rèn)為是同源的。在源值中不考慮路徑。
下面是方案、主機和端口不匹配(因而是不同源)的例子:
和
和、:8080和
:8081
下面的例子中URL是同源的:
/pagel.html和/page2.html
跨文檔消息傳遞通過允許消息在不同源之間交換,克服了同源策略的限制。當(dāng)你發(fā)送消息
時,發(fā)送者指定接收者的源;當(dāng)你接收消息時,發(fā)送者的源會被作為消息的一部分。消息
的源由瀏覽器提供,不會被偽造。在接收者一端,你可以決定處理哪些消息,忽略哪些消
息。你還可以保留一個“白名單”,只處理求自具有信任源的文檔的消息。
跨文檔消息傳遞是HTML5規(guī)范利用非常強大的API簡化Web應(yīng)用程序之間通信的絕佳
范例。但是,它的重點被限制在跨窗口、選項卡和iFrame的通信上。它不能解決協(xié)議通
信中正在變得越來越嚴(yán)重的復(fù)雜性,這時我們就要求助WebSocketo
HTML5規(guī)范的主要編寫者IanHickson在HTML5規(guī)范的通信部分中添加了我們今天所說
的WebSocket。WebSocket最初稱作TCPConnection,現(xiàn)已發(fā)展為一個獨立的規(guī)范。雖然
WebSocket目前存在于HTML5的領(lǐng)域之外,但是它對于實現(xiàn)現(xiàn)代(基于HTML5的)
Web應(yīng)用程序中的實時連接性至關(guān)重要。那么,為什么WebSocket對今天的Web如此
有意義呢?我們首先來看看舊的HTTP架構(gòu),在這種架構(gòu)中辦議通信非常重要。
1.3舊的HTTP架構(gòu)概覽
為了理解WebSocket的重要性,我們首先來看看舊的架構(gòu),具體地說就是使用HTTP的
架構(gòu)。
1.3.1HTTP101(即HTTP/1.0和HTTP/1.1)
在舊的架構(gòu)中,連接性由HTTP/1.0和HTTP/1.1處理。HTTP是客戶端/服務(wù)器模式中請
求響應(yīng)所用的協(xié)議,在這種模式中,客戶端(一般是Web瀏覽器)向服務(wù)器提交HTTP
請求,服務(wù)器響應(yīng)請求的資源(例如HTML頁面)和關(guān)于頁面的附加信息。HTTP也用來
讀取文檔:HTTP/1.0對于從服務(wù)器請求單個文檔來說已經(jīng)足夠。但是,隨著Web的成
長超出了簡單的文檔共享,并開始包含更多的交互性,連接性需要進行微調(diào),以縮短瀏覽
器請求和服務(wù)器響應(yīng)之間的時間。
在HTTP/1.0中,每個服務(wù)器請求需要一個單獨的連接,這種方法至少可以說沒有太好的
伸縮性(scalability)。HTTP的下一個修訂版本HTTP/1.1增加了可重用連接。由于可重
用連接的推出,瀏覽器可以初始化一個到Web服務(wù)器的連接,以讀取HTML頁面,然后
重用該連接讀取圖片、腳本等資源。HTTP/1.1通過減少客戶端到服務(wù)器的連接數(shù)量,降
低了請求的延遲。
HTTP是無狀態(tài)的,也就是說,它將每個請求當(dāng)成唯一和獨立的。無狀態(tài)協(xié)議具有一些優(yōu)
勢,例如,服務(wù)器不需要保存有關(guān)會話的信息,從而不需要存儲數(shù)據(jù)。但是,這也意味著
在每次HTTP請求和響應(yīng)中都會發(fā)送關(guān)于請求的冗余信息。
我們來看看客戶端對服務(wù)器請求的一個例子。代碼清單1-1展示了包含多個HTTP首標(biāo)的
完整HTTP請求。
代碼清單1-1客戶端對服務(wù)器請求的HTTP/1.1首標(biāo)
GET/PollingStock/PollingStockHTTP/1.1Host:localhost:8080User-Agent:Mozilla/5.0
(Windows;U;WindowsNT5.1;en-US;rv:)Gecko/20091102Firefox/3.5.5Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language:en-us
Accept-Encoding:gzip,deflateAccept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.7Keep-Alive:
300Connection:keep-aliveReferer:http://)ocalhost:8080/PollingStock/Cookie:
show!nheritedConstant=false;show!nheritedProtectedConstant=false;
showInheritedProperty=false;showInheritedProtectedProperty=false;
showInheritedMethod=false;showlnheritedProtectedMethod=false;
showInheritedEvent=false;showInheritedStyle=false;showlnheritedEffect=false;
代碼清單1-2展示了服務(wù)器對客戶端響應(yīng)的一個示例。
代碼清單1-2服務(wù)器對客戶端時應(yīng)的HTTP1.1首標(biāo)
HTTP/l.x200OKX-Powered-By:Servlet/2.5Server:SunJavaSystemApplicationServer
9.1_02Content-Type:text/html;charset=UTF-8Content-Leng:h:321Date:Wed,06Dec
201200:32:46GMT
在代碼清單1-1和代碼清單1-2中,僅僅首標(biāo)信息的開銷就有871字節(jié)(這還沒有實際
的數(shù)據(jù))。這兩個例了說明,不管服務(wù)器是否向客戶端發(fā)送實際的數(shù)據(jù)或者信息,請求的
首標(biāo)信息都必須在兩個方向上傳輸:從客戶端到服務(wù)器和從服務(wù)器到客戶端。
在HTTP/1.0和HTTP/1.1中,低效的根源主要是:
HTTP用于文檔共享,而不是豐富的交互性應(yīng)用程序,我們在桌面上習(xí)以為常的這種應(yīng)用
程序現(xiàn)在已經(jīng)進入Web;隨著客戶端和服務(wù)器之間交互的增加,HTTP協(xié)議在客戶端和
服務(wù)器之間通信所需要的信息量快速增加。
從根本上講,HTTP還是半雙工的協(xié)議,也就是說,在同?時刻流量只能單向流動:客戶
端向服務(wù)器發(fā)送請求(單向),然后服務(wù)器響應(yīng)請求(單向)。半雙工的效率很低。想象
一下這樣的電話交談:當(dāng)你想要交流時,你必須按下一個按鈕,說話,再按下另一個按鈕
完成。同時,你的通話對象必須耐心等待你講完,按下按鈕,最后回復(fù)。是不是很熟悉?
我們兒時小規(guī)模地進行過這種形式的通信,美國軍隊始終采用這種方式:步話機。雖然步
話機有絕時的好處和很好的應(yīng)用,但是并不總是最有效的通常形式。
工程師們多年來一直致力于解決這個問題,他們使用各種著名的方法:輪詢、長輪詢和
HTTP流化(streaming)。
1.3.2繞道而行:HTTP輪詢、長輪詢和流化
通常,瀏覽器訪問網(wǎng)頁時,會向頁面所在的服務(wù)器發(fā)送一個HTTP請求。Web服務(wù)器確
認(rèn)請求并向瀏覽器發(fā)回響應(yīng)。在許多情況下,返回的信息(如股價、新聞、交通圖、醫(yī)療
設(shè)備讀數(shù)和天氣信息)到達瀏覽器顯示頁面時已經(jīng)過時。如果用戶需要得到最新的實時信
息,他們可以不斷刷新頁面,但是這顯然并不實際,也不是特別精妙的解決方案。
當(dāng)前對提供實時Web應(yīng)用程序的嘗試多半圍繞“輪詢”(polling)技術(shù)進行,這種技術(shù)模
擬其他服務(wù)器端“推”技術(shù)(最沆行的是Comet),本質(zhì)上就是推遲完成HTTP響應(yīng),向客
戶端提交信息。
輪詢是一種定時的同步調(diào)用,客戶端向服務(wù)器發(fā)送請求查看是否有可用的新信息。請求以
固定的時間間隔發(fā)出,不管是否有信息,客戶端都會得到響應(yīng):如果有可用信息,服務(wù)器
發(fā)送這些信息:如果沒有可用信息,服務(wù)器返回一個拒絕響應(yīng),客戶端關(guān)閉連接。
如果你知道信息交付的精確間隔,輪詢就是一個好的解決方案,因為你可以同步客戶端,
只在你知道服務(wù)器上有可用信息的時候發(fā)送請求。然而,實時數(shù)據(jù)并不總是可以預(yù)測的,
發(fā)出不必要的請求、因而打開過多連接是不可避免的。結(jié)果是,在低信息率的情況下,你
可能打開或者關(guān)閉許多不必要的連接。
長輪詢(longpolling)是另一種流行的通信方法,客戶端向服務(wù)器請求信息,并在設(shè)定
的時間段內(nèi)打開一個連接。服務(wù)器如果沒有任何信息,會保持請求打開,直到有客戶端可
用的信息,或者直到指定的超時時間用完為止。這時,客戶端重新向服務(wù)器請求信息。長
輪詢也稱作Comet(前面已經(jīng)提到過)或者反向AJAX。Comet延長HTTP響應(yīng)的完成,
直到服務(wù)器有需要發(fā)送給客戶端的內(nèi)容,這種技術(shù)常常稱作"掛起GET,喊“擱置POST%
重要的是要知道,當(dāng)信息量很大時,長輪詢相對于傳統(tǒng)輪詢并沒有明顯的性能優(yōu)勢,因為
客戶端必須頻繁地重連到服務(wù)器以讀取新信息,造成網(wǎng)絡(luò)的表現(xiàn)和快速輪詢相同。長輪詢
的另一個問題是缺乏標(biāo)準(zhǔn)實現(xiàn)c
任流化技術(shù)中,客戶端發(fā)送一個請求,服務(wù)器發(fā)送并維護一個持續(xù)更新和保持打開(可以
是無限或者規(guī)定的時間段)的開放響應(yīng)。每當(dāng)服務(wù)器有需要交付給客戶端的信息時,它就
更新響應(yīng)??雌饋?,流化是能夠適應(yīng)不可預(yù)測的信息交付的吸佳方案,但是服務(wù)器從不發(fā)
出完成HTTP響應(yīng)的請求,從而使連接一直保持打開。在這種情況卜,代理和防火墻可能
緩存響應(yīng),導(dǎo)致信息交付的延遲增加。因此,許多流化的嘗拭對于存在防火墻和代理的網(wǎng)
絡(luò)是不友好的。
二述方法提供了近乎?實時的通信,但是它們也涉及HTTP請求和響應(yīng)首標(biāo),包含了許多附
加和不必要的首標(biāo)數(shù)據(jù)與延遲c此外,在每一種情況下,客戶端都必須等待請求返回,才
能發(fā)出后續(xù)的請求,而這顯著地增加了延遲。
圖1-2展示了Web上這些連接的半雙工特性,它們整合到架構(gòu)中,其中在內(nèi)聯(lián)網(wǎng)中具有
通過TCP的全雙工連接。
圖1-2在Web上是半雙工;在后端是通過TCP的全雙工
1.4WebSocket入門
那么,我們該往何處去?為了消除這些問題,HTML5規(guī)范的連接性部分包含了
WebSocketoWebSocket是一種自然的全雙工、雙向、單套接字連接。使用WebSocket,
你的HTTP請求變成打開WebSocket連接(WebSocket或者WebSocketoverTLS
(TransportLayerSecurity,傳輸層安全性,原稱"SSL"))的單一請求,并且重用從客戶
端到服務(wù)器以及服務(wù)器到客戶端的同一連接。
WebSocket減少了延遲,因為一旦建立起WebSocket連接,服務(wù)器可以在消息可用時發(fā)
送它們。例如,和輪詢不同,WebSocket只發(fā)出一個請求。服畀器不需要等待來自客戶
端的請求。相似地,客戶端可以在任何時候向服務(wù)器發(fā)送消息。相比輪詢不管是否有可用
消息,每隔一段時間都發(fā)送一個請求,單一請求大大減少了延遲。
圖1-3比較「輪詢和WebSocket方案。
時間50ms100ms150ms200ms250ms
時I可50ms100ms150ms200ms250ms?
圖1-3輪詢與WebSocket
本質(zhì)上,WebSocket和HTML5語義及簡單化范式融為一體。它不僅消除了復(fù)雜的變通方
法需求以及延時,而且簡化了架構(gòu)。接下來我們更深入地探討這方面的理由。
1.5為什么需要WebSocket
我們已經(jīng)研究了WebSocket的歷史,現(xiàn)在再來看看使用WebSocket的一些理由。
1.5.1WebSocket與性能相關(guān)
WebSocket使實時通信更加有效。
你總是可以在HTTP上使用輪詢(有時候甚至是流化),通過HTTP接收通知。然而,
WebSocket能節(jié)約帶寬、CPU資源并減少延遲。
WebSocket是性能上的一個革新。
1.5.2WebSocket與簡潔性相關(guān)
WebSocket使Web上客戶端和服務(wù)器之間的通信變得更加簡單。
用WebSocket之前的架構(gòu)建立過實時通信的人們就會知道,HTTP上的實時通知技術(shù)過
于復(fù)雜。在無狀態(tài)的請求之間維護會話狀態(tài)更增加了復(fù)雜度??缭碅JAX十分難以理解,
用AJAX處理有序的請求需要特殊考慮,而AJAX通信也很復(fù)雜。將HTTP擴展到它不適
用的用例的每個嘗試都會增加軟件的復(fù)雜度。
WebSocket可以顯著簡化實時應(yīng)用程序中面向連接的通信。
1.5.3WebSocket與標(biāo)準(zhǔn)相關(guān)
WebSocket是一個低層網(wǎng)絡(luò)協(xié)議,你可以在它的基礎(chǔ)上構(gòu)建其他標(biāo)準(zhǔn)協(xié)議。
許多Web應(yīng)用程序?qū)嶋H上很龐大。大部分AJAX應(yīng)用程序通常都包含了緊密耦合的客戶
端和服務(wù)器組件。WebSocket自然支持高層應(yīng)用協(xié)議的概念,你可以更加靈活地獨立發(fā)
展客戶端和服務(wù)器。支持較高層的協(xié)議使模塊化成為可能,鼓勵開發(fā)可重用組件。例如,
你可以使用相同的XMPPoverWebsocket客戶端登錄不同的聊天服務(wù)器,因為所有XMPP
服務(wù)器都理解相同的標(biāo)準(zhǔn)協(xié)議C
Websocket是可互操作Web應(yīng)用程序的?個革新。
1.5.4WebSocket4HTML5相關(guān)
WebSocket是為HTML5應(yīng)用程序提供高級功能,以便與其池平臺競爭所作努力的一部分。
每種操作系統(tǒng)都需要網(wǎng)絡(luò)功能,應(yīng)用程序打開套接字以及與其他主機通信的能力是每個主
要平臺提供的核心特性。HTML5在許多方面傾向于使瀏覽器成為一個與操作系統(tǒng)相仿的
全功能應(yīng)用程序平臺。低級網(wǎng)絡(luò)API(如套接字)無法處理源安全模型或者Web的API
設(shè)計風(fēng)格。WebSocket為HTML5應(yīng)用程序提供了TCP風(fēng)格的網(wǎng)絡(luò),沒有破壞瀏覽器安
全性,而且有一個現(xiàn)代的API。
WebSocket是HTML5平臺的關(guān)鍵組件,也是開發(fā)人員的強大工具。
1.5.5你需要WebSocket
簡單地說,你需要WebSocket來構(gòu)建世界級的Web應(yīng)用程序。WebSocket解決了使
HTTP不適合于實時通信的主要不足之處。WebSocket的異步、雙向通信模式是對
Internet上的傳輸層協(xié)議提供的總體靈活性的I可報。
想想WebSocket的各種出色應(yīng)用,以及在應(yīng)用程序中構(gòu)建真正的實時功能,例如聊天、
協(xié)作文檔編輯、大型多人在線游戲(MassivelyMultiplayerOnline,MMO)、股票交易應(yīng)
用程序等。我們將在本書后面介紹具體的應(yīng)用程序。
1.6WebSocket和RFC6455
WebSuckel是個協(xié)議,但是還有個WebSockelAPI,應(yīng)用程序可以用它控制
WebSocket協(xié)議,響應(yīng)服務(wù)器觸發(fā)的事件。這個API由W3C(WorldwideWeb
Consortium,萬維網(wǎng)聯(lián)盟)開發(fā),而協(xié)議由IETF(InternetEngineeringTaskForce,互
聯(lián)網(wǎng)工程任務(wù)組)開發(fā)。WebSocketAPI現(xiàn)在得到現(xiàn)代瀏覽器的支持,包含了使用全雙工、
雙向WebSocket連接所需的方法和特性(attribute)。利用這個API,你可以執(zhí)行必要的
操作,例如打開和關(guān)閉連接、發(fā)送和接收消息、、監(jiān)聽服務(wù)器觸發(fā)的事件。第2章將更加
詳細(xì)地描述這個API,并提供使用它的例子。
WebSocket協(xié)議能夠通過Web進行客戶端和遠(yuǎn)程服務(wù)器之間的全雙工通信,并支持二進
制數(shù)據(jù)和文本字符串的傳輸。這個協(xié)議由開始的握手和之后的基本消息框架組成,在TCP
二添加層次。第3章將更加詳細(xì)描述協(xié)議,并說明如何創(chuàng)建自己的WebSocket服務(wù)器。
1.7WebSocket的世界
WebSocketAPI和協(xié)議都有十分繁榮的社區(qū),這通過各種WebSocket服務(wù)器選擇、開發(fā)
人員社區(qū)和大量廣泛使用的WebSocket應(yīng)用程序得到了反映。
1.8WebSocket的選擇
WebSocket服務(wù)器的實現(xiàn)多種多樣,例如Apachemod_pyweb-socket、Jetty>Socket.IO
和Kaazing的WebSocketGatewayo
寫作木書的想法來源于我們渴望分享在Kaazing多年使用WebSocket及相關(guān)技術(shù)中得到
的知識、經(jīng)驗和意見。Kazzing花費5年多的時間,構(gòu)建了一個企業(yè)級的WebSocket網(wǎng)
關(guān)服務(wù)器及其客戶端程序庫。
1.8.1非?;钴S的WebSocket社區(qū)
我們已經(jīng)列出了使用WebSocket的一些原因,并將探索自己動手實現(xiàn)WebSocket的實用
示例。除了各種可用的WebSocket服務(wù)器之外,WebSocket社區(qū)也十分興旺,特別是在
HTML5游戲、企業(yè)級消息傳遞和在線聊天方面。每天都有許多會議和編碼研討會,不僅
討論HTML5的特定領(lǐng)域,而且討論實時通信方法,尤其是WebSocket。連許多構(gòu)建廣為
使用的企業(yè)級消息服務(wù)的公司也將WebSocket集成到它們的系統(tǒng)中。因為WebSocket是
基于標(biāo)準(zhǔn)的,所以很容易改進現(xiàn)有架構(gòu),標(biāo)準(zhǔn)化和擴展實現(xiàn),也很容易構(gòu)建過去不可能或
者難以建立的新服務(wù)。
WebSocket的激動人心之處還反映在GitHub等在線社區(qū)上,每天社區(qū)中都會創(chuàng)建更多的
WebSocket相關(guān)服務(wù)器、應(yīng)用程序和項目。其他興旺的社區(qū)有
/,我們在后續(xù)章節(jié)中將使用它提供的一個WebSocket服務(wù)器
示例,還有和,它們都是鼓勵分享所有與
HTML5(包括WebSocket)相關(guān)信息的開放社區(qū)。
說明附錄B中列出了更多的WebSocket服務(wù)器。
1.8.2WebSocket應(yīng)用程序
在寫作本書時,WebSocket正被用在各種各樣的應(yīng)用程序中,有些應(yīng)用程序可能使用了
以前的“實時”通信技術(shù)(如AJAX),但是它們已經(jīng)顯著地改進了性能。外幣兌換和股票
報價應(yīng)用程序也從WebSocket提供的降低帶寬需求和全雙工連接特性中得到了好處。第
3章將研究如何檢杳WebSocket流量。
隨著部署到瀏覽器的應(yīng)用程序的增加,HTML5游戲的開發(fā)也有了迅猛的發(fā)展。
WebSocket從本質(zhì)上很適合于Web游戲,因為游戲及其交互很依賴響應(yīng)能力。使用
WebSocket的HTML5游戲?qū)嵗ㄔ诰€賭博應(yīng)用程序、集成WebGLoverWebSocket的
游戲控制器應(yīng)用程序以及游戲中的在線聊天。還有一些很有趣的大型多人在線游戲
(MM0)廣泛地用于各種移動及桌面設(shè)備的瀏覽器中。
1.9相關(guān)技術(shù)
你可能吃驚地發(fā)現(xiàn),有一些技術(shù)可以和WebSocket結(jié)合使用或者代替WebSocket。下面
是其他一些新興的Web通信技術(shù)。
1.9.1服務(wù)器發(fā)送事件
如果架構(gòu)需要雙向全雙工通信,那么WebSocket是個好的選擇。然而,如果你的服務(wù)主
要向其客戶端廣播或者推送信息,而不需要任何交互(如新聞?wù)?、天氣預(yù)報等),那么
使用服務(wù)器發(fā)送事件(Server-SentEvent,SSE)提供的EventSourceAPI是個好的選擇。
SSE是HTML5規(guī)范的一部分,加強了某些Comet技術(shù)??梢詫SE當(dāng)作一種HTTP鴕
詢、長輪詢和流化的公用可互操作語法使用。利用SSE,你可以得到自動重連、事件ID
等功能。
說明盡管WebSocket和SSE連接都以HTTP請求開始,但是你所看到的性能優(yōu)勢和功能
可能有很大的不同。例如,SSE不能從客戶端向服務(wù)器匕傳流化數(shù)據(jù),且只支持文本數(shù)據(jù)。
1.9.2SPDY
SPDY(音同“Speedy")是Google開發(fā)的一種網(wǎng)絡(luò)協(xié)議,得到越來越多的瀏覽器支持,包
ISGoogleChrome>Opera和MozillaFirefox。本質(zhì)上,SPDY擴充了HTTP,通過壓縮
HTTP首標(biāo)和多路復(fù)用(multiplexing)等手段改進HTTP請求性能。它的主要目的是改
進網(wǎng)頁的性能。WebSocket的重點是改進Web應(yīng)用程序前端和服務(wù)器之間的通信,而
SPDY優(yōu)化的是應(yīng)用程序內(nèi)容和靜態(tài)頁面的交付。HTTP和WebSocket之間的不同是架構(gòu)
性的,而不是增量的。SPDY是HTTP的修改形式,所以它有與HTML相同的架構(gòu)風(fēng)格和
語義。它改正了許多HTTP的非本質(zhì)問題,添加了多路豆用、工作管道(workingpipling)
和其他有用的改進。WebSocket去除了請求響應(yīng)風(fēng)格的通信并啟用實時交互和替代的架
構(gòu)模式。
WebSocket和SPDY是相互補充的,你可以將SPDY擴充的HTTP連接升級為WebSocket,
從而在SPDY上使用WebSocket,從兩個領(lǐng)域獲得利益。
1.9.3Web實時通信
Web實時通信(WebReal-TimeCommunication,WebRTC)是增強現(xiàn)代Web瀏覽器通
信能力的另一種努力。WebRTC是Web的點對點技術(shù)。瀏覽器可以直接通信,而不需要
通過服務(wù)器傳輸所有的數(shù)據(jù)。WebRTC包含可以讓瀏覽器相互之間實時通信的API。在寫
作本書時,WebRTC由萬維網(wǎng)聯(lián)盟(W3C)草擬,仍處于草案階段,可以在
/TR/webrtc/上找至I」。
WebRTC的第一批應(yīng)用是實時語音和視頻聊天。WebRTC對于媒體應(yīng)用程序已經(jīng)是具有
吸引力的新技術(shù),網(wǎng)上有許多示例應(yīng)用程序,你可以用它們測試Web上的視頻和音頻傳
輸。
WebRTC以后將會添加數(shù)據(jù)通道。這些數(shù)據(jù)通道計劃使用和WebSocket類似的API以保
持一致性。此外,如果你的應(yīng)用程序使用了流媒體和其他數(shù)據(jù),可以結(jié)合使用WebRTC
和WebSocketo
1.10小結(jié)
本章介紹了HTML5和WebSocket,以及一些HTTP演變到WebSocket的歷史。我們希
弟,你現(xiàn)在已經(jīng)和我們一樣興奮地學(xué)習(xí)WebSocket,研究代碼,并且夢想著用它所能實
現(xiàn)的宏偉目標(biāo)。
后續(xù)章節(jié)將更深入地研究WebSocketAPI和協(xié)議,說明如何將WebSocket與標(biāo)準(zhǔn)的、更
高級的應(yīng)用程序協(xié)議相結(jié)合,討論WebSocket的安全性,并描述企業(yè)級特性和部署。
第2章WebSocketAPI
2.1WebSocketAPI概覽
本章介紹WebSocket應(yīng)用程序編程接口(API),你可以用它來控制WebSocket協(xié)議,
創(chuàng)建WebSocket應(yīng)用程序。我們研究WebSocketAPI的各個組成部分,包括事件、方法
和特性。為了學(xué)習(xí)使用API,我們寫了一個簡單的客戶端應(yīng)用程序。將其連接到現(xiàn)有的公
共服務(wù)器(http:〃),這樣我們就可以通過WebSocket發(fā)送和接收消息。
通過使用現(xiàn)有的服務(wù)器,我們可以將重點放在學(xué)習(xí)用丁?創(chuàng)建WebSocket應(yīng)用程序的易用
API上。我們還將循序漸進地說明如何使用WebSocketAPI驅(qū)動使用二進制數(shù)據(jù)的
HTML5媒體。最后,我們將討論瀏覽器支持和連接性。
本章重點研究WebSocket的客戶端應(yīng)用程序方面,你可以將WebSocket協(xié)議擴展到自己
的Web應(yīng)用程序中。后續(xù)章節(jié)將更加詳細(xì)地描述WebSocket協(xié)議,以及在具體環(huán)境中使
用WebSocket的方法。
正如第1章所提到的,WebSocket由網(wǎng)絡(luò)協(xié)議和幫助建立客戶端應(yīng)用程序與服務(wù)器之間
WebSocket連接的API組成。第3章將更加詳細(xì)地描述WebSocket協(xié)議,現(xiàn)在先來看看
API。
WebSocketAPI是一個接口,使應(yīng)用程序能使用WebSocket協(xié)議。通過在應(yīng)用程序中使
用這個API,可以控制應(yīng)用程序用于發(fā)送和接收消息的全雙工通信信道。WebSocket接口
非常簡單易用。要連接到遠(yuǎn)程主機,只要創(chuàng)建一個新的WebSocket對象實例,并為新對
象提供一個代表所要連接端口的URL就可以了。
WebSocket連接通過在客戶端和服務(wù)器之間第一次握手時將HTTP協(xié)議升級到
WebSocket協(xié)議來完成,這一工作在相同的底層TCP連接上進行。一旦建立,
WebSocket消息可以在WebSocket接口定義的方法之間來回傳送。在應(yīng)用程序代碼中,
可以使用異步事件監(jiān)聽器處理連接生.命周期的每個階段。
WebSocketAPI完全是(真正的)事件驅(qū)動的。一旦建立全雙工連接,當(dāng)服務(wù)器有需要發(fā)
送到客戶端的數(shù)據(jù),或者你所關(guān)心的資源將要改變狀態(tài)時,它會自動發(fā)送數(shù)據(jù)或者通知。
有了事件驅(qū)動的API,你就不需要輪詢服務(wù)器以得到目標(biāo)資源的最新狀態(tài),客戶端只要監(jiān)
聽需要的通知和更改就行了。
在后面幾章討論更高層協(xié)議(如STOMP和XMPP)時,我們將看到使用WebSocketAPI
的不同示例。但是現(xiàn)在,我們要更仔細(xì)地研究API。
2.2WebSocketAPI入門
WebSocketAPI使你可以通過Web,在客戶端應(yīng)用程序和服務(wù)器端進程之間建立全雙工
的雙向通信。WebSocket接口規(guī)定了可用于客戶端的方法以及客戶端與網(wǎng)絡(luò)的交互方式,
首先,你要調(diào)用WebSocket構(gòu)造函數(shù)(constructor),創(chuàng)建一個WebSocket連接。構(gòu)造
函數(shù)返回WebSocket對象實例。你可以監(jiān)聽該對象上的事件,這些事件告訴你何時連接
打開,何時消息到達,何時連接關(guān)閉以及何時發(fā)生錯誤。你可以與WebSocket對象交互,
發(fā)送消息或者關(guān)閉連接。下面來研窕WebSocketAPI的各個方面。
2.2.1WebSocket構(gòu)造函數(shù)
為了建立到服務(wù)器的WebSocket連接,使用WebSocket接口,通過指向一個代表所要連
接端點的URL,實例化一個WebSocket對象。WebSocket桃議定義了兩種URL方案
(URLscheme)—ws和wss,分別用于客戶端和服務(wù)器之間的非加密與加密流量。ws
(WebSocket)方案與HTTPURI方案類似。wss(WebSocketSecure,WebSocket安全)
URI方案表示使用傳輸層安全性(TLS,也叫SSL)的WebSocket連接,使用HTTPS采
用的安全機制來保證HTTP連接的安全。
說明第7章將詳細(xì)討論WebSocket安全性。
WebSocket構(gòu)造函數(shù)有一個必需的參數(shù)URL(指向連接目標(biāo)的URL)和?個可選參數(shù)
protocols(為了建立連接,服務(wù)器必須在其響應(yīng)中包含的一個或一組協(xié)議名稱)。在
protocols參數(shù)中可以使用的協(xié)議包括XMPP(extensibleMessagingandPresence
Protocol,可擴展消息處理現(xiàn)場協(xié)議)、SOAP(SimpleObjectAccessProtocol,簡單對象
訪問協(xié)議)或者自定義協(xié)議。
代碼清單2-1展示了WebSocket構(gòu)造函數(shù)的必需參數(shù),它必須是以ws:〃或者ws:〃開始
的一個完全限定的URLo在這個例子中,完全限定URL是ws:〃。如
果URL有語法錯誤,構(gòu)造函數(shù)將拋出異常。
代碼清單2-1WebSocket構(gòu)造函數(shù)示例
//CreatenewWebSocketconnectionvarws=new
WcbSocket("ws://www.");
連接到WebSocket服務(wù)器時,可以選擇使用第二個參數(shù)列出應(yīng)用程序支持的協(xié)議,用于
協(xié)議協(xié)商。
為了確保客戶端和服務(wù)器發(fā)送與接收雙方都能理解的消息,它們必須使用相同的協(xié)議。
WebSocket構(gòu)造函數(shù)允許你定義客戶端用于與服務(wù)器通信的協(xié)議。服務(wù)器反過來選擇使
用的協(xié)議(在客戶端和服務(wù)器之間只能使用一種協(xié)議)。這些協(xié)議在WebSocket協(xié)議之
二使用。WebSocket的最大好處之一是能在WebSocket上建立廣泛使用的協(xié)議層次(將
在第3章?第6章介紹),使你可以完成許多出色的工作,例如將傳統(tǒng)的桌面應(yīng)用程序
帶到Web中。
說明WebSocket協(xié)議(RFC6455)將與WebSocket一起使用的協(xié)議稱作“子協(xié)議”,盡管
這些協(xié)議是更高級、結(jié)構(gòu)完整的協(xié)議。在本書中,我們一般簡單地將和WebSocket一起
使用的協(xié)議稱作“協(xié)議”,以免引起混淆。
我們離題太遠(yuǎn)了,現(xiàn)在回到API中的WebSocket構(gòu)造函數(shù)。在第一次WebSocket連接提
手時(你將在第3章中學(xué)到更多的內(nèi)容),客戶發(fā)送帶有協(xié)議名稱的5"-亞曲5呢1<?"
Protocol首標(biāo)。服務(wù)器選擇0個或者1個協(xié)議,響應(yīng)一個帶有和客戶請求相同的協(xié)議名
稱的Sec-WebSocket-Protocol首標(biāo);否則,服務(wù)器關(guān)閉連接,
孫議協(xié)商對于確定WebSocket服務(wù)器支持的協(xié)議及版本很有用。應(yīng)用程序可能支持多個
林議,使用協(xié)議協(xié)商選擇與特定服務(wù)器通信的協(xié)議。代碼清單2-2展示了支持假想?yún)f(xié)議
"myProtocol"的WebSocket構(gòu)造函數(shù)。
代碼清單2-2帶有協(xié)議支持的WebSocket構(gòu)造函數(shù)示例
//ConnectingtotheserverwithoneprotocolcalledmyProtocolvarws=new
WebSocket("ws://","myProtocol");
說明在代碼清單2-2中,假想的協(xié)議"myProtocol”是一個精心定義、甚至可能是注冊和標(biāo)
準(zhǔn)化的協(xié)議名稱,客戶端應(yīng)用程序和服務(wù)器都能理解這個協(xié)灰。
WebSocket構(gòu)造函數(shù)還可以包含一組客戶端支持的協(xié)議,讓服務(wù)器決定使用其中的一個,
代碼清單2-3展示了一個WebSocket構(gòu)造函數(shù)的例子,以數(shù)組的形式表示其支持的協(xié)議
列表。
代碼清單2-3帶有協(xié)議支持的WebSocket構(gòu)造函數(shù)示例
//ConnectingtotheserverwithmultipleprotocolchoicesvarechoSocket=new
WebSocket("ws://",["com.kaazing.echo",
"tocol"]}echoSocket.onopen=function(e){//Checktheprotocol
chosenbytheserverconsole.log(echoStocol);}
在代碼清單2-3中,由于WebSocket服務(wù)器ws://只理解
com.kaazing.echo協(xié)議,而不理解tocoL該服務(wù)器在觸發(fā)
WebSocketopen事件的時候選擇com.kaazing.echo協(xié)議。使用數(shù)組為你提供了讓應(yīng)用程
序?qū)Σ煌?wù)器使用不同協(xié)議的靈活性。
第3章將深入討論WebSocket協(xié)議,但是實際上,可以在protocols參數(shù)中指定的協(xié)議
有三種類型:
注冊協(xié)議:已經(jīng)根據(jù)RFC6455(WebSocket協(xié)議),向注冊協(xié)議的正式管理實體1ANA
(InternetAssignedNumbersAuthority,互聯(lián)網(wǎng)編號分配機構(gòu))正式注冊的標(biāo)準(zhǔn)協(xié)議。
注冊協(xié)議的例子之一是Microsoft的SOAPoverWebSocket協(xié)議。更多信息參見
/assignments/websocket/websocket.xmlo開放協(xié)議:廣泛使用的
標(biāo)準(zhǔn)化協(xié)議,如XMPP和STOMP,它們尚未注冊為正式的標(biāo)準(zhǔn)協(xié)議。我們將在后續(xù)章節(jié)
里研究這些協(xié)議類型的使用。自定義協(xié)議:你自己編寫并且和WebSocket一起使用的協(xié)
議。
本章重點關(guān)注符WebSocketAPI用于你的自定義協(xié)議,后續(xù)的章節(jié)將研究開放協(xié)議的使
用。我們首先單獨地了解事件、對象和方法,然后將它們組合為一個可行的示例。
2.2.2WebSocket事件
WebSocketAPI是純事件驅(qū)動的。應(yīng)用程序代碼監(jiān)聽WebSocket對象上的事件,以便處
理輸入數(shù)據(jù)和連接狀態(tài)的改變cWebSocket協(xié)議也是事件驅(qū)動的。客戶端應(yīng)用程序不需
要輪詢服務(wù)器來得到更新的數(shù)據(jù)。消息和事件將在服務(wù)器發(fā)送它們的時候異步到達。
WebSocket編程遵循異步編程模式,也就是說,只要WebSocket連接打開,應(yīng)用程序就
簡單地監(jiān)聽事件。客戶端不需要主動輪詢服務(wù)器得到更多的言息。要開始監(jiān)聽事件,只要
為WebSocket對象添加回調(diào)函數(shù)。也可以使用addEventListenerQDOM方法為
WebSocket對象添加事件監(jiān)聽器。
WebSocket對象調(diào)度4個不同的事件:
openmessageerrorclose
和所有WebAPI一樣,可以用on<事件名稱>處理程序?qū)傩员O(jiān)聽這些事件,也可以使用
addEvcntListcner。;方法。
1.WebSocket事件:open
一旦服務(wù)器響應(yīng)了WebSocket連接請求,open事件觸發(fā)并建立一個連接。open事件對
應(yīng)的回調(diào)函數(shù)稱作onopen?
代碼清單2-4說明建立WebSocket連接時如何處理該事件。
代碼清單2-4open事件處理程序示例
//EventhandlerfortheWebSocketconnectionopeningws.onopen=function(e)
{console.log("Connectionopen...");};
到open事件觸發(fā)時,協(xié)議握手已經(jīng)完成,WebSocket已經(jīng)準(zhǔn)備好發(fā)送利接收數(shù)據(jù)。如果
應(yīng)用程序接收到一個open事件,那么可以確定WebSocket服務(wù)器成功地處理了連接請
求,并且同意與應(yīng)用程序通信C
2.WebSocket事件:message
WebSocket消息包含來自服務(wù)器的數(shù)據(jù)。你也可能聽說過組成WebSocket消息的
WebSocket幀(Frame)。第3章將詳細(xì)討論消息和幀的概念。為了理解消息使用API
的方式,WebSocketAPI只輸出完整的消息,而不是WebSocket幀。message事件在接
收到消息時觸發(fā),對應(yīng)于該事件的回調(diào)函數(shù)是onmessageo
代碼清單2-5展示了一個接收文本消息并顯示消息內(nèi)容的消息處理程序。
代碼清單2-5文本消息message事件處理程序示例
//Eventhandlerforreceivingtextmessagesws.onmessage=function(e){ifftypeofe.data
==="string"){console.log("Stringmessagereceived'1,e,e.data);}else{console.log("Other
messagereceived",e,e.data);}};
除了文本,WebSocket消息還可以處理二進制數(shù)據(jù),這種數(shù)據(jù)作為Blob消息(見代碼清
單2-6)或者ArrayBuffer消息處理(見代碼清單2-7)。因為設(shè)置WebSocket消息二進
制數(shù)據(jù)類型的應(yīng)用程序會影響二進制消息,所以必須在讀取數(shù)據(jù)之前決定用于客戶端二進
制輸入數(shù)據(jù)的類型。
代碼清單2-6Blob消息message事件處理程序示例
//SetbinaryTypetoblob(Blobisthedefault.)ws.binaryType="blob";//Eventhandler
forreceivingBlobmessagesws.onmessage=function(e){iffe.datainstanceof
Blob){console.log("Blobmessagereceived",e.data);varblob=newBlob(e.data);});
代碼清單2-7展示了一個檢查和處理ArrayBuffer消息的處理程序。
代碼清單2-7ArrayBuffer消息message事件處理程序示例
//SetbinaryTypetoArrayBuffermessagesws.binaryType='arraybuffer";//Event
handlerforreceivingArrayBuffermessagesws.onmessage=function(e){iffe.data
instanceofArrayBuffer){console.logf'ArrayBufferMessageReceived",+e.data);//e.data
isanArrayBuffer.Createabyteviewofthatobject,vara=newUint8Array(e.dataJ;}};
3.WebSocket事件:error
error事件在響應(yīng)意外故障的時候觸發(fā)。與該事件對應(yīng)的回調(diào)函數(shù)為onerror。錯誤還會
導(dǎo)致WebSocket連接關(guān)閉。如果你接收一個error事件,可以預(yù)期很快就會觸發(fā)close事
件。dose事件中的代碼和原因有時候能告訴你錯誤的根源。error事件處理程序是調(diào)用
服務(wù)器重連邏輯以及處理來自WebSocket對象的異常的最佳場所。代碼清單2-8展示了
監(jiān)聽error事件的一個例子。
代碼清單2-8error事件處理程序示例
//EventhandlerforerrorsintheWebSocketobjectws.onerror=function(e)
{console.Iog("WebSocketError:",e);//Customfunctionforhandlingerrors
handleErrors(e);};
4.WebSocket事件:close
close事件在WebSocket連接關(guān)閉時觸發(fā)。對應(yīng)于close事件的回調(diào)函數(shù)是onclose。
旦連接關(guān)閉,客戶端和服務(wù)器不再能接收或者發(fā)送消息。
說明WebSocket規(guī)范還定義\ping和pong幀,可以用于持續(xù)連接(keep-alive)、心跳、
網(wǎng)絡(luò)狀態(tài)檢測、延遲測量等,但是WebSocketAPI目前沒有輸出這些特性。盡管瀏覽器
接受ping幀,但是不會觸發(fā)對應(yīng)WebSocket上的ping事件。相反,瀏覽器將自動響應(yīng)
pong幀。然而,瀏覽器實例化的ping如果在一段時間內(nèi)沒有得到pong應(yīng)答,可能會觸
發(fā)連接的close事件。第8章將詳細(xì)介紹WebSocket的ping和pong。
當(dāng)調(diào)用close。方法終止與服務(wù)器的連接時,也會觸發(fā)onclose事件處理程序,如代碼清單
2-9所示。
代碼清單2-9close事件處理程序示例
//Eventhandlerforclosedconnectionsws.onclose=function(e){console.log("Connection
closed",e);};
WebSocketclose事件在連接美閉時觸發(fā),這可能有多種原因,比如連接失敗或者成功的
WebSocket關(guān)閉握手。WebSocket對象特性readyState反映了連接的狀態(tài)(2為正在關(guān)
閉,3為己關(guān)閉)。
dose事件有3個有用的屬性(property),可以用于錯誤處理和恢復(fù):wasClean^code
和error。wasQean屬性是一個布爾屬性,表示連接是否順利關(guān)閉。如果WebSocket的
關(guān)閉是對來自服務(wù)器的一個close幀的響應(yīng),則該屬性為true。如果連接是因為其他原因
(例如,因為底層TCP連接關(guān)閉)關(guān)閉,則該屬性為falseocode和reason屬性表示服
務(wù)器發(fā)送的關(guān)閉握手狀態(tài)。這些屬性和WebSocket.close。方法中的code和reason參數(shù)
一致,我們將在本章后面詳加介紹。在第3章中,我們將在討論WebSocket協(xié)議時討論
關(guān)閉的代碼和它們的含義。
說明關(guān)于WebSocket事件的更多細(xì)節(jié),參見WebSocketAPI規(guī)范:
http://www.w3.Org/TR/wcbsockets/o
2.2.3WebSocket方法
WebSocket對象有兩個方法:send。和close。。
1.WebSocket方法:send()
使用WebSocket在客戶端和服務(wù)器之間建立全雙工雙向連接后,就可以在連接打開時
(也就是說,在調(diào)用。nopen監(jiān)聽器之后,調(diào)用。nclose監(jiān)聽器之前)調(diào)用send。方法。
使用send。方法可以從客戶端向服務(wù)器發(fā)送消息。在發(fā)送一條或者多條消息之后,可以
保持連接打開,或者調(diào)用close。方法終止連接。
代碼清單2-10是向服務(wù)器發(fā)送文本消息的?個例子。
代碼清單2-10通過WebSocket發(fā)送一條文本消息
//Sendatextmessagews.sendf'HelloWebSocket!");
send。方法在連接打開的時候發(fā)送數(shù)據(jù)。如果連接不可用或者關(guān)閉,它拋出一個有關(guān)無效
連接狀態(tài)的異常。人們開始使用WebSocketAPI時常犯的?個錯誤是試圖在連接打開之
前發(fā)送消息,如代碼清單2-11所示。
代碼清單2-11試圖在打開連接之前發(fā)送消息
//Openaconnectionandtrytosendamessage.(Thiswillnotwork!)varws=new
WebSocket("ws://")ws.send("Initialdata");
代碼清單2-11不能正常工作,因為連接尚未打開。你應(yīng)該等待。pen事件觸發(fā),才能在
新構(gòu)造的WebSocket上發(fā)送笫一條消息,如代碼清單2-12所示。
代碼清單2-12在發(fā)送消息之前等待open事件
//Waituntiltheopeneventbeforecallingsend().varws=new
WebSocket("ws://")ws.onopen=function(e){ws.send("Initialdata");}
如果想發(fā)送消息響應(yīng)另一個事件,可以檢查WebSocketreadyState屬性,并選擇只在套
接字打開時發(fā)送數(shù)據(jù),如代碼清單2-13所示。
代碼清單2-13檢查readyState屬性了解WebSocket是否打開
//Handleoutgoingdata.SendonaWebSocketifthatsocketisopen,function
myEventHandler(data){if(ws.readyState===WebSocket.OPEN){//Thesocketisopen,
soitisoktosendthedata,ws.send(data);}else{//Dosomethingelseinthiscase.
//Possiblyignorethedataorenqueueit.}}
除了文木(字符串)消息之外,WebSocketAPI允許發(fā)送二進制數(shù)據(jù),這對于實現(xiàn)二進制
悔議特別有用。這樣的二進制協(xié)議可能是TCP上層的標(biāo)準(zhǔn)互聯(lián)網(wǎng)協(xié)議,這些協(xié)議的載荷
可能是Blob或ArrayBuffer?代碼清單2-14是通過WebSocket發(fā)送二進制消息的一個示
例。
代碼清單2-14通過WebSocket發(fā)送二進制消息
//SendaBlobvarblob=newBlobf'blobcontents");ws.send(blob);//Sendan
ArrayBuffervara=newUint8Array([8,6,7,5,3,0,9]);ws.send(a上uffer);
說明第6章將展示一個通過WebSocket發(fā)送二進制數(shù)據(jù)的例子。
Blob對象在與JavaScriptFileAPI結(jié)合使用以發(fā)送和接收文件時特別有用,這些文件主要
有多媒體文件、圖像、視頻和音頻。本章最后的示例代碼結(jié)合WebSocketAPI和
JavaScriptFileAPI,讀取文件內(nèi)容,并將其作為WebSocket消息發(fā)送。
2.WebSocket方法:close()
使用close。方法,可以關(guān)閉WebSocket連接或者終止連接嘗試。如果連接已經(jīng)關(guān)閉,該
方法就什么都不做。在調(diào)用close。之后,不能在已經(jīng)關(guān)閉的WebSocket上發(fā)送任何數(shù)據(jù)。
代碼清單2-15展示了close。方法的一個例子。
代碼清單2-15調(diào)用close。方法
//ClosetheWebSocketconnectionws.closef);
可以向close。方法傳遞兩個可選參數(shù):code(數(shù)字型的狀態(tài)代碼)和reason(—個文本
字符中)。傳遞這些參數(shù)能夠向服務(wù)器傳遞關(guān)于客戶關(guān)閉連買原囚的信息。我們將在笫3
章中介紹WebSocket關(guān)閉握手時詳細(xì)討論狀態(tài)代碼和原因。代碼清單2-16展示了調(diào)用帶
參數(shù)的close。方法的一個例子,
代碼清單2-16帶有原因的close。方法調(diào)用
//ClosetheWebSocketconnectionbecausethesessionhasendedsuccessfully
v/s.close(1000,"Closingnormally");
代碼清單2-16使用了代碼1000,正如代碼中所描述的,這表示連接正常關(guān)閉。
2.2.4WebSocket對象特性
可以使用多種WebSocket對象特性提供關(guān)于WebSocket對象的更多信息:readyState>
hufferedAmount和protocol?
1.WebSocket對象特性:readyState
WebSocket對象通過只讀特性readyState報告其連接狀態(tài),你在前面的幾節(jié)中己經(jīng)學(xué)到
了一點相關(guān)的知識。這個屬性根據(jù)連接狀態(tài)自動變化,并提供關(guān)于WcbSockct連接的有
用信息。
表2-1描述了用于描述連接狀態(tài)的readyState特性的4個不同值。
表2-1readyState特性、取值和狀態(tài)描述
特性常量取值狀態(tài)WebSocket.CONNECTING0連接正在進行中,但還未建立
WebSocketOPEN1連接已經(jīng)建立。消息可以在客戶端和服務(wù)器之間傳遞
WebSocket.CLOSING2連接正在進行關(guān)閉握手WebSocket.CLOSED3連接己經(jīng)關(guān)閉,不能
打開
信息來源:萬維網(wǎng)聯(lián)盟,2012年。
正如WebSocketAPI所描述的,當(dāng)WebSocket對象笫一次創(chuàng)建時,readyState為0,表
示套接字正在連接。了解WebSocket連接的當(dāng)前狀態(tài)有助于應(yīng)用程序的調(diào)試,例如,確
保在嘗試開始向服務(wù)器發(fā)送請求之前已經(jīng)打開了WebSocket連接。這一信息對于了解連
接的生命周期也很有用。
2.WebSocket對象特性:bufferedAmount
設(shè)計應(yīng)用程序時,你可能想要檢查發(fā)往服務(wù)器的緩沖數(shù)據(jù)量,特別是在客戶端應(yīng)用程序向
服務(wù)器發(fā)送大量數(shù)據(jù)的時候。盡管調(diào)用send。是立即生效的,但是數(shù)據(jù)在互聯(lián)網(wǎng)上的傳
輸卻不是如此。瀏覽器將為你的客戶端應(yīng)用程序緩存出站數(shù)據(jù),從而使你可以隨時調(diào)用
send。,發(fā)送任意數(shù)量的數(shù)據(jù)。然而,如果你想知道數(shù)據(jù)在網(wǎng)絡(luò)上傳送的速率,
WebSocket對象可以告訴你緩存的大小。你可以使用bufferedAmount特性檢查已經(jīng)進入
隊列,但是尚未發(fā)送到服務(wù)器的字節(jié)數(shù)。這個特性報告的值不包括協(xié)議組幀開銷或者操作
系統(tǒng)、網(wǎng)絡(luò)硬件所進行的緩沖,
代碼清單2-17展示一個使用bufferedAmount特性每秒發(fā)送更新的例子。如果網(wǎng)絡(luò)無法
承受這一速率,它會相應(yīng)地作出調(diào)整。
代碼清單2-17bufferedAmount示例
//10kmaxbuffersize,varTHRESHOLD=10240;//CreateaNewWebSocketconnection
varws=newWebSocket("ws:///updates");//Listenfortheopening
eventws.onupen=fuiiclion(){//Allenipllosendupdateeverysecond.
setlnterval(functionQ{//Sendonlyifthebufferisnotfullif(ws.bufferedAmount<
THRESHOLD){ws.send(getApplicationState());}},1000);};
對■于限制應(yīng)用向服務(wù)器發(fā)送數(shù)據(jù)的速率,從而避免網(wǎng)絡(luò)飽和,bufferedAmount特性很有
用。
專家提示你可以在試圖關(guān)閉連接之前檢查對象的bufferedAmount特性,確定是否有些數(shù)
據(jù)還沒有從應(yīng)用中發(fā)送到服務(wù)器。
3.WebSocket對象特性:protocol
在前面關(guān)于WebSocket構(gòu)造函數(shù)的討論中,我們提到了protocol參數(shù),它讓服務(wù)器知道
客戶端理解并可在WebSocket上使用的協(xié)議。WebSocket對象的protocol特性提供了另
一條關(guān)于WebSocket實例的有用信息。客戶端和服務(wù)器協(xié)議協(xié)商的結(jié)果可以在
WebSocket對象看到。protocol特性包含在打開握手期間WebSocket服務(wù)器選擇的協(xié)
議名,換句話說,protocol特性告訴你特定WebSocket上使用的協(xié)議。protocol特性在
最初的握手完成之前為空,如果服務(wù)器沒有選擇客戶端提供的某個協(xié)議,該特性保持空值。
2.3全部組合起來
現(xiàn)在,我們已經(jīng)簡單了解了WebSocket構(gòu)造函數(shù)、事件、特性和方法,可以將所學(xué)的
WebSocketAPI相關(guān)知識組合起來了。這里,我們創(chuàng)建了一個客戶端應(yīng)用程序,通過
Web與一臺遠(yuǎn)程服務(wù)器通信,用WebSocket交換數(shù)據(jù)。我們的JavaScript客戶端示例使
用ws:〃上的“回顯”服務(wù)器,它可以接收并返回你發(fā)送到服務(wù)器的任
何消息。使用同顯服務(wù)器對于純粹的客戶端測試很有用,特別是用于理解WebSocketAPI
與服務(wù)器的交互方式。
首先,我們創(chuàng)建連接,然后在網(wǎng)頁上顯示我們的代碼觸發(fā)的事件,這來自于服務(wù)器。頁面
將顯示連接到服務(wù)器的客戶端的相關(guān)信息,向服務(wù)器發(fā)送消息并從服務(wù)器接收消息,然后
從服務(wù)器斷開。
代碼清單2-18展示了服務(wù)器通信和消息傳遞的一個完整示例。
代碼清單2-18使用WebSocketAPI的完整客戶端應(yīng)用程序
WebSocketEchoClient
WebsocketEchoClient
在運行網(wǎng)頁之后,輸出類似于下面這樣:
WebSocketSampleClientConnectedMessagesentMessagereceived:HelloWebSocket!
Disconnected
如果你看到這一輸出,那么恭喜你,你已經(jīng)成功創(chuàng)建并執(zhí)行了第一個WebSo
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 選煤廠人員安全培訓(xùn)試題及答案解析
- 吉林省松原市醫(yī)院消防安全測試題九(含答案)
- 江蘇省常州市醫(yī)院潔凈室消防安全測試題十九(含答案)
- 加盟生產(chǎn)合同(標(biāo)準(zhǔn)版)
- 人民銀行安全員考試題庫及答案解析
- 啤酒廠級安全培訓(xùn)試題及答案解析
- 幼兒園語言能力提升工作規(guī)劃方案
- 市場營銷管理及企業(yè)產(chǎn)品推廣方案
- 腫瘤科常用化療方案教案(2025-2026學(xué)年)
- 家裝質(zhì)量擔(dān)保承諾書(3篇)
- 《活潑的金屬單質(zhì)-鈉》教案
- 麻精藥培訓(xùn)課件
- 護士(血液透析室)考試試題及答案
- 近三年安全生產(chǎn)業(yè)績證明
- 投資者關(guān)系管理與投資者策略
- 冠脈造影手術(shù)病人的護理
- 項目風(fēng)險管理預(yù)案
- 員工進出閘口管理制度
- JG/T 324-2011建筑幕墻用陶板
- 廠區(qū)防雷接地管理制度
- T/CECS 10187-2022無機復(fù)合聚苯不燃保溫板
評論
0/150
提交評論