|
[本文屬原創(chuàng),如有轉載,請注明出處http://blog.csdn.net/yl02520/article/] WebSocket是html5新增加的一種通信協議,目前流行的瀏覽器都支持這個協議,例如Chrome,Safari,Firefox,Opera,IE等等,對該協議支持最早的應該是chrome,從chrome12就已經開始支持,隨著協議草案的不斷變化,各個瀏覽器對協議的實現也在不停的更新。該協議還是草案,沒有成為標準,不過成為標準應該只是時間問題了,從WebSocket草案的提出到現在已經有十幾個版本了,目前最新的是版本17,所對應的協議版本號為13,目前對該協議支持最完善的瀏覽器應該是chrome,畢竟WebSocket協議草案也是Google發(fā)布的。 1. WebSocket API簡介 首先看一段簡單的javascript代碼,該代碼調用了WebSockets的API。
這份代碼總共只有5行,現在簡單概述一下這5行代碼的意義。 第一行代碼是在申請一個WebSocket對象,參數是需要連接的服務器端的地址,同http協議使用http://開頭一樣,WebSocket協議的URL使用ws://開頭,另外安全的WebSocket協議使用wss://開頭。 第二行到第五行為WebSocket對象注冊消息的處理函數,WebSocket對象一共支持四個消息 onopen, onmessage, onclose和onerror,當Browser和WebSocketServer連接成功后,會觸發(fā)onopen消息;如果連接失敗,發(fā)送、接收數據失敗或者處理數據出現錯誤,browser會觸發(fā)onerror消息;當Browser接收到WebSocketServer發(fā)送過來的數據時,就會觸發(fā)onmessage消息,參數evt中包含server傳輸過來的數據;當Browser接收到WebSocketServer端發(fā)送的關閉連接請求時,就會觸發(fā)onclose消息。我們可以看出所有的操作都是采用消息的方式觸發(fā)的,這樣就不會阻塞UI,使得UI有更快的響應時間,得到更好的用戶體驗。 [本文屬原創(chuàng),如有轉載,請注明出處http://blog.csdn.net/yl02520/article/] Browser已經支持http協議,為什么還要開發(fā)一種新的 WebSocket協議呢?我們知道http協議是一種單向的網絡協議,在建立連接后,它只允許Browser/UA(UserAgent)向 WebServer發(fā)出請求資源后,WebServer才能返回相應的數據。而WebServer不能主動的推送數據給Browser/UA,當初這么設 計http協議也是有原因的,假設WebServer能主動的推送數據給Browser/UA,那Browser/UA就太容易受到攻擊,一些廣告商也會 主動的把一些廣告信息在不經意間強行的傳輸給客戶端,這不能不說是一個災難。那么單向的http協議給現在的網站或Web應用程序開發(fā)帶來了哪些問題呢? 讓我們來看一個案例,現在假設我們想開發(fā)一個基于Web的應用程序去 獲取當前Web服務器的實時數據,例如股票的實時行情,火車票的剩余票數等等,這就需要Browser/UA與WebServer端之間反復的進行 http通信,Browser不斷的發(fā)送Get請求,去獲取當前的實時數據。下面介紹幾種常見的方式: 1. Polling
這種方式就是通過Browser/UA定時的向Web服務器發(fā)送 http的Get請求,服務器收到請求后,就把最新的數據發(fā)回給客戶端(Browser/UA),Browser/UA得到數據后,就將其顯示出來,然后 再定期的重復這一過程。雖然這樣可以滿足需求,但是也仍然存在一些問題,例如在某段時間內Web服務器端沒有更新的數據,但是Browser/UA仍然需 要定時的發(fā)送Get請求過來詢問,那么Web服務器就把以前的老數據再傳送過來,Browser/UA把這些沒有變化的數據再顯示出來,這樣顯然既浪費了 網絡帶寬,又浪費了CPU的利用率。如果說把Browser發(fā)送Get請求的周期調大一些,就可以緩解這一問題,但是如果在Web服務器端的數據更新很快 時,這樣又不能保證Web應用程序獲取數據的實時性。 2. Long Polling
上面介紹了Polling遇到的問題,現在介紹一下LongPolling,它是對Polling的一種改進。 Browser/UA發(fā)送Get請求到Web服務器,這時Web服務 器可以做兩件事情,第一,如果服務器端有新的數據需要傳送,就立即把數據發(fā)回給Browser/UA,Browser/UA收到數據后,立即再發(fā)送Get 請求給Web Server;第二,如果服務器端沒有新的數據需要發(fā)送,這里與Polling方法不同的是,服務器不是立即發(fā)送回應給Browser/UA,而是把這個 請求保持住,等待有新的數據到來時,再來響應這個請求;當然了,如果服務器的數據長期沒有更新,一段時間后,這個Get請求就會超 時,Browser/UA收到超時消息后,再立即發(fā)送一個新的Get請求給服務器。然后依次循環(huán)這個過程。 這種方式雖然在某種程度上減小了網絡帶寬和CPU利用率等問題,但是 仍然存在缺陷,例如假設服務器端的數據更新速率較快,服務器在傳送一個數據包給Browser后必須等待Browser的下一個Get請求到來,才能傳遞 第二個更新的數據包給Browser,那么這樣的話,Browser顯示實時數據最快的時間為2×RTT(往返時間),另外在網絡擁塞的情況下,這個應該 是不能讓用戶接受的。另外,由于http數據包的頭部數據量往往很大(通常有400多個字節(jié)),但是真正被服務器需要的數據卻很少(有時只有10個字節(jié)左 右),這樣的數據包在網絡上周期性的傳輸,難免對網絡帶寬是一種浪費。 通過上面的分析可知,要是在Browser能有一種新的網絡協議,能支持客戶端和服務器端的雙向通信,而且協議的頭部又不那么龐大就好了。WebSocket就是肩負這樣一個使命登上舞臺的。 [本文屬原創(chuàng),如有轉載,請注明出處http://blog.csdn.net/yl02520/article/] WebSocket協議是一種雙向通信協議,它建立在TCP之上,同http一樣通過TCP來傳輸數據,但是它和http最大的不同有兩 點:1.WebSocket是一種雙向通信協議,在建立連接后,WebSocket服務器和Browser/UA都能主動的向對方發(fā)送或接收數據,就像 Socket一樣,不同的是WebSocket是一種建立在Web基礎上的一種簡單模擬Socket的協議;2.WebSocket需要通過握手連接,類 似于TCP它也需要客戶端和服務器端進行握手連接,連接成功后才能相互通信。 下面是一個簡單的建立握手的時序圖:
這里簡單說明一下WebSocket握手的過程。 當Web應用程序調用new WebSocket(url)接口時,Browser就開始了與地址為url的WebServer建立握手連接的過程。 1. Browser與WebSocket服務器通過TCP三次握手建立連接,如果這個建立連接失敗,那么后面的過程就不會執(zhí)行,Web應用程序將收到錯誤消息通知。 2. 在TCP建立連接成功后,Browser/UA通過http協議傳送WebSocket支持的版本號,協議的字版本號,原始地址,主機地址等等一些列字段給服務器端。 例如:
3. WebSocket服務器收到Browser/UA發(fā)送來的握手請求后,如果數據包數據和格式正確,客戶端和服務器端的協議版本號匹配等等,就接受本次握手連接,并給出相應的數據回復,同樣回復的數據包也是采用http協議傳輸。
4. Browser收到服務器回復的數據包后,如果數據包內容、格式都沒有問題的話,就表示本次連接成功,觸發(fā)onopen消息,此時Web開 發(fā)者就可以在此時通過send接口想服務器發(fā)送數據。否則,握手連接失敗,Web應用程序會收到onerror消息,并且能知道連接失敗的原因。 [本文屬原創(chuàng),如有轉載,請注明出處http://blog.csdn.net/yl02520/article/] WebSocket與http協議一樣都是基于TCP的,所以他們都是可靠的協議,Web開發(fā)者調用的WebSocket的send函數在 browser的實現中最終都是通過TCP的系統接口進行傳輸的。WebSocket和Http協議一樣都屬于應用層的協議,那么他們之間有沒有什么關系 呢?答案是肯定的,WebSocket在建立握手連接時,數據是通過http協議傳輸的,正如我們上一節(jié)所看到的“GET/chat HTTP/1.1”,這里面用到的只是http協議一些簡單的字段。但是在建立連接之后,真正的數據傳輸階段是不需要http協議參與的。 具體關系可以參考下圖:
[本文屬原創(chuàng),如有轉載,請注明出處http://blog.csdn.net/yl02520/article/] 如果要搭建一個Web服務器,我們會有很多選擇,市場上也有很多成熟的產品供我們應 用,比如開源的Apache,安裝后只需簡單的配置(或者默認配置)就可以工作了。但是如果想搭建一個WebSocket服務器就沒有那么輕松了,因為 WebSocket是一種新的通信協議,目前還是草案,沒有成為標準,市場上也沒有成熟的WebSocket服務器或者Library實現 WebSocket協議,我們就必須自己動手寫代碼去解析和組裝WebSocket的數據包。要這樣完成一個WebSocket服務器,估計所有的人都想 放棄,幸好的是市場上有幾款比較好的開源庫供我們使用,比如PyWebSocket,WebSocket-Node, LibWebSockets等等,這些庫文件已經實現了WebSocket數據包的封裝和解析,我們可以調用這些接口,這在很大程度上減少了我們的工作 量。 下面就簡單介紹一下這些開源的庫文件。 1. PyWebSocket PyWebSocket采用Python語言編寫,可以很好的跨平臺,擴展起來也比較簡單,目前WebKit采用它搭建WebSocket服務器來做LayoutTest。 我們可以獲取源碼通過下面的命令 svn checkouthttp://pywebsocket./svn/trunk/ pywebsocket-read-only 更多的詳細信息可以從http://code.google.com/p/pywebsocket/獲取。 2. WebSocket-Node WebSocket-Node采用JavaScript語言編寫,這個庫是建立在nodejs之上的,對于熟悉JavaScript的朋友可參考一下,另外Html5和Web應用程序受歡迎的程度越來越高,nodejs也正受到廣泛的關注。 我們可以從下面的連接中獲取源碼 https://github.com/Worlize/Websocket-Node 3. LibWebSockets LibWebSockets采用C/C++語言編寫,可定制化的力度更大,從TCP監(jiān)聽開始到封包的完成我們都可以參與編程。 我們可以從下面的命令獲取源代碼 git clone git://git.warmcat.com/libwebsockets |
|
|
來自: 云端素館 > 《移動開發(fā)》