轉自: http://www.cnblogs.com/shanyou/p/4085802.htmlhtml
按照OSI網絡分層模型,IP是網絡層協議,TCP是傳輸層協議,而HTTP和MQTT是應用層的協議。在這三者之間, TCP是HTTP和MQTT底層的協議。你們對HTTP很熟悉,這裏簡要介紹下MQTT。MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸)是IBM開發的一個即時通信協議,有可能成爲物聯網的重要組成部分。該協議支持全部平臺,幾乎能夠把全部聯網物品 和外部鏈接起來,被用來當作傳感器的通訊協議。web
HTTP協議通過多年的使用,發現了一些不足,主要是性能方面的,包括: 算法
HTTP的鏈接問題,HTTP客戶端和服務器之間的交互是採用請求/應答模式,在客戶端請求時,會創建一個HTTP鏈接,而後發送請求消息,服務端給出應答消息,而後鏈接就關閉了。(後來的HTTP1.1支持持久鏈接)
由於TCP鏈接的創建過程是有開銷的,若是使用了SSL/TLS開銷就更大。 瀏覽器
在瀏覽器裏,一個網頁包含許多資源,包括HTML,CSS,JavaScript,圖片等等,這樣在加載一個網頁時要同時打開鏈接到同一服務器的多個鏈接。 安全
HTTP消息頭問題,如今的客戶端會發送大量的HTTP消息頭,因爲一個網頁可能須要50-100個請求,就會有至關大的消息頭的數據量。 服務器
HTTP通訊方式問題,HTTP的請求/應答方式的會話都是客戶端發起的,缺少服務器通知客戶端的機制,在須要通知的場景,如聊天室,遊戲,客戶端應用須要不斷地輪詢服務器。 websocket
而 WebSocket是從不一樣的角度來解決這些不足中的一部分。還有其餘技術也在針對這些不足提出改進。 網絡
本質上來講,WebSocket是不限於 HTTP協議的,可是因爲現存大量的HTTP基礎設施,代理,過濾,身份認證等等,WebSocket借用HTTP和HTTPS的端口。因爲使用HTTP 的端口,所以TCP鏈接創建後的握手消息是基於HTTP的,由服務器判斷這是一個HTTP協議,仍是WebSocket協議。 WebSocket鏈接除了創建和關閉時的握手,數據傳輸和HTTP沒丁點關係了。 session
歷時11年,WebSocket終於被批准成爲IETF的建議標準:RFC6455.其前身是WHATWG (Web Hypertext Application Technology Working Group)的工做。而Web Socket的API,是W3C的工做。socket
WebSocket能夠只打開一個到服務器的連接,而且在此連接上交換信息。其優點在於減小了傳統方法的複雜性,提升了可靠性和下降了瀏覽器和客戶端之間的負載。這樣作的一個重要緣由是,不少防火牆屏蔽80之外的端口,迫使愈來愈多的應用遷移到HTTP上來了。
11年的websocket草案的變遷中,有的瀏覽器支持的是舊版本的websocket,好比iPhone4上的safari使用的WebSocket是舊版的握手協議,那麼就要使用就的握手協議來製作服務器端。現在只有Safari支持舊版本的協議,Chrome和Firefox最新版都已升級至Hybi-10(協議地址)。所以,咱們再來看一下WebSocket新版協議Hybi-10。此次協議變動很是大,主要集中在握手協議和數據傳輸的格式上。
握手協議
咱們先來看一下大體的區別:
服務器生成驗證的方式變化較大,咱們來作一介紹。
舊版:
1 GET / HTTP/1.1
2 Upgrade: WebSocket
3 Connection: Upgrade
4 Host: 127.0.0.1:1337
5 Origin: http://127.0.0.1:8000
6 Cookie: sessionid=xxxx; calView=day; dayCurrentDate=1314288000000
7 Sec-WebSocket-Key1: cV`p1* 42#7 ^9}_ 647 08{
8 Sec-WebSocket-Key2: O8 415 8x37R A8 4
9 ;"######
舊版生成Token的方法以下:
取出Sec-WebSocket-Key1中的全部數字字符造成一個數值,這裏是1427964708,而後除以Key1中的空格數目,獲得一個數值,保留該數值整數位,獲得數值N1;對Sec-WebSocket-Key2採起一樣的算法,獲得第二個整數N2;把N1和N2按照Big- Endian字符序列鏈接起來,而後再與另一個Key3鏈接,獲得一個原始序列ser_key。Key3是指在握手請求最後,有一個8字節的奇怪的字符串";"######",這個就是Key3。而後對ser_key進行一次md5運算得出一個16字節長的digest,這就是老版本協議須要的 token,而後將這個token附在握手消息的最後發送回Client,便可完成握手。
新版:
1 GET / HTTP/1.1
2 Upgrade: websocket
3 Connection: Upgrade
4 Host: 127.0.0.1:1337
5 Sec-WebSocket-Origin: http://127.0.0.1:8000
6 Sec-WebSocket-Key: erWJbDVAlYnHvHNulgrW8Q==
7 Sec-WebSocket-Version: 8
8 Cookie: csrftoken=xxxxxx; sessionid=xxxxx
新版生成Token的方法以下:
首先服務器將key(長度24)截取出來,如4tAjitqO9So2Wu8lkrsq3w==,用它和自定義的一個字符串(長度 36)258EAFA5-E914-47DA-95CA-C5AB0DC85B11鏈接起來,而後把這一字符串進行SHA-1算法加密,獲得長度爲20字節的二進制數據,再將這些數據通過Base64編碼,最終獲得服務端的密鑰,也就是ser_key。服務器將ser_key附在返回值Sec- WebSocket-Accept後,至此握手成功。
WebSocket也有本身一套幀協議。數據報文格式以下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
0 1 2 3 01234567890123456789012345678901 +-+-+-+-+-------+-+-------------+-------------------------------+ |F|R|R|R|opcode|M|Payload len| Extended payload length | |I|S|S|S| (4) |A| (7) | (16/63) | |N|V|V|V| |S| | (ifpayload len==126/127) | ||1|2|3| |K| | | +-+-+-+-+-------+-+-------------+---------------+ | Extended payload length continued,ifpayload len==127 | +---------------+-------------------------------+ | |Masking-key,ifMASK set to1 | +-------------------------------+-------------------------------+ |Masking-key(continued) | Payload Data | +-----------------------------------------------+ : Payload Data continued... : +-------------------------------+ | Payload Data continued... | +---------------------------------------------------------------+ |
FIN:1位,用來代表這是一個消息的最後的消息片段,固然第一個消息片段也多是最後的一個消息片段;
RSV1, RSV2, RSV3: 分別都是1位,若是雙方之間沒有約定自定義協議,那麼這幾位的值都必須爲0,不然必須斷掉WebSocket鏈接;
Opcode:4位操做碼,定義有效負載數據,若是收到了一個未知的操做碼,鏈接也必須斷掉,如下是定義的操做碼:
Mask:1位,定義傳輸的數據是否有加掩碼,若是設置爲1,掩碼鍵必須放在masking-key區域,客戶端發送給服務端的全部消息,此位的值都是1;
Payload length: 傳輸數據的長度,以字節的形式表示:7位、7+16位、或者7+64位。若是這個值以字節表示是0-125這個範圍,那這個值就表示傳輸數據的長度;若是這個值是126,則隨後的兩個字節表示的是一個16進制無符號數,用來表示傳輸數據的長度;若是這個值是127,則隨後的是8個字節表示的一個64位無符合數,這個數用來表示傳輸數據的長度。多字節長度的數量是以網絡字節的順序表示。負載數據的長度爲擴展數據及應用數據之和,擴展數據的長度可能爲0,於是此時負載數據的長度就爲應用數據的長度。
Masking-key:0或4個字節,客戶端發送給服務端的數據,都是經過內嵌的一個32位值做爲掩碼的;掩碼鍵只有在掩碼位設置爲1的時候存在。
Payload data: (x+y)位,負載數據爲擴展數據及應用數據長度之和。
Extension data:x位,若是客戶端與服務端之間沒有特殊約定,那麼擴展數據的長度始終爲0,任何的擴展都必須指定擴展數據的長度,或者長度的計算方式,以及在握手時如何肯定正確的握手方式。若是存在擴展數據,則擴展數據就會包括在負載數據的長度以內。
Application data:y位,任意的應用數據,放在擴展數據以後,應用數據的長度=負載數據的長度-擴展數據的長度。
3、 MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸)是輕量級基於代理的發佈/訂閱的消息傳輸協議,設計思想是開放、簡單、輕量、易於實現。這些特色使它適用於受限環境。例如,但不只限於此:
該協議的特色有:
早在1999年,IBM的Andy Stanford-Clark博士以及Arcom公司ArlenNipper博士發明了MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸)技術。BM和St. Jude醫療中心經過MQTT開發了一套Merlin系統,該系統使用了用於家庭保健的傳感器。St. Jude醫療中心設計了一個叫作Merlin@home的心臟裝置,這種無限發射器能夠用來監控那些已經植入復律-除顫器和起搏器(二者都是基本的傳感 器)的心臟病人。
該產品利用MQTT把病人的即時更新信息傳給醫生/醫院,而後醫院進行保存。這樣的話,病人就不用親自去醫院檢查心臟儀器了,醫生能夠隨時查看病人的數據,給出建議,病人在家裏就能夠自行檢查。
IBM稱該發射器包括一個大型觸摸屏,一個嵌入式鍵盤平臺,以及一個Linux操做系統。
在將來幾年,MQTT的應用會愈來愈廣,值得關注。
經過MQTT協議,目前已經擴展出了數十個MQTT服務器端程序,能夠經過PHP,JAVA,Python,C,C#等系統語言來向MQTT發送相關消息。
此外,國內不少企業都普遍使用MQTT做爲 Android手機客戶端與服務器端推送消息的協議。其中Sohu,Cmstop手機客戶端中均有使用到MQTT做爲消息推送消息。據Cmstop主要負 責消息推送的高級研發工程師李文凱稱,隨着移動互聯網的發展,MQTT因爲開放源代碼,耗電量小等特色,將會在移動消息推送領域會有更多的貢獻,在物聯網 領域,傳感器與服務器的通訊,信息的收集,MQTT均可以做爲考慮的方案之一。在將來MQTT會進入到咱們生活的各各方面。
若是須要下載MQTT服務器端,能夠直接去MQTT官方網站點擊software進行下載MQTT協議衍生出來的各個不一樣版本。
MQTT和TCP、WebSocket的關係能夠用下圖一目瞭然:
MQTT協議專一於網絡、資源受限環境,創建 之初未曾考慮WEB環境。HTML5 Websocket是創建在TCP基礎上的雙通道通訊,和TCP通訊方式很相似,適用於WEB瀏覽器環境。雖然MQTT基因層面選擇了TCP做爲通訊通 道,但咱們添加個編解碼方式,MQTT over Websocket也能夠的。這樣作的好處,MQTT的使用範疇被擴展到HTML五、桌面端瀏覽器、移動端WebApp、Hybrid等,多了一些想像空 間。這樣看來,不管是移動端,仍是WEB端,MQTT都會有本身的使用空間。