即時通訊相關技術總結

解決問題

即時通訊要解決三方面的問題:javascript

  1. 雙全工通訊
  2. 低延時
  3. 支持跨域

各類即時通訊技術

輪詢

客戶端定時向服務器發送Ajax請求,服務器接到請求後立刻返回響應信息並關閉鏈接。
優勢:後端程序編寫比較容易。
缺點:請求中有大半是無用,浪費帶寬和服務器資源。
實例:適於小型應用。php

長輪詢

客戶端向服務器發送Ajax請求,服務器接到請求後hold住鏈接,直到有新消息才返回響應信息並關閉鏈接,客戶端處理完響應信息後再向服務器發送新的請求。
優勢:在無消息的狀況下不會頻繁的請求。
缺點:服務器hold鏈接會消耗資源。
實例:WebQQ、Hi網頁版、Facebook IM。html

長鏈接

在頁面裏嵌入一個隱蔵iframe,將這個隱蔵iframe的src屬性設爲對一個長鏈接或是採用xhr請求的請求,服務器端就能源源不斷地往客戶端輸入數據。
優勢:消息即時到達,不發無用請求。
缺點:服務器維護一個長鏈接會增長開銷。
實例:Gmail聊天
技術細節:
● XHR 利用onreadystatechange=3去作一些事:當它的readyState爲3的時候,獲取它的responseText而後進行處理,readyState爲3表示數據傳送中,整個通訊過程尚未結束,因此它還在不斷獲取服務端發送過來的數據,直到readyState爲4的時候才表示數據發送完畢,一次通訊過程結束。
● 利用Iframe作一些事: 低版本的IE不容許在XHR的readyState爲3的時候獲取其responseText屬性,爲了達到在IE上使用這個技術,又出現了基於iframe的數據流通訊方式。在瀏覽器中動態載入一個iframe,讓它的src屬性指向請求的服務器的URL,實際上就是向服務器發送了一個http請求,而後在瀏覽器端建立一個處理數據的函數,在服務端經過iframe與瀏覽器的長鏈接定時輸出數據給客戶端,可是這個返回的數據並非通常的數據,而是一個相似於<script type="text/javascript">parent.process('"+randomNum.toString()+"')</script>腳本執行的方式,瀏覽器接收到這個數據就會將它解析成js代碼並找到頁面上指定的函數去執行,其實是服務端間接使用本身的數據間接調用了客戶端的代碼,達到實時更新客戶端的目的。
● 動態生成一個htmlfile對象,這個對象ActiveX形式的com組件,它實際上就是一個在內存中實現的HTML文檔,經過將生成的iframe添加到這個內存中的HTMLfile中,並利用iframe的數據流通訊方式達到上面的效果。同時因爲HTMLfile對象並非直接添加到頁面上的,因此並無形成瀏覽器顯示正在加載的現象。代碼以下。java

Flash Socket

在頁面中內嵌入一個使用了Socket類的 Flash 程序JavaScript經過調用此Flash程序提供的Socket接口與服務器端的Socket接口進行通訊,JavaScript在收到服務器端傳送的信息後控制頁面的顯示。
優勢:實現真正的即時通訊,而不是僞即時。
缺點:客戶端必須安裝Flash插件;非HTTP協議,沒法自動穿越防火牆。
實例:網絡互動遊戲。web

SSE 服務器推送事件

爲了解決瀏覽器只可以單向傳輸數據到服務端可以實現客戶端請求服務端,而後服務端利用與客戶端創建的這條通訊鏈接push數據給客戶端,客戶端接收數據並處理的目的。從獨立的角度看,SSE技術提供的是從服務器單向推送數據給瀏覽器的功能,可是配合瀏覽器主動請求,實際上就實現了客戶端和服務器的雙向通訊。它的原理是在客戶端構造一個eventSource對象,該對象具備readySate屬性,分別表示以下:後端

webSocket(HTML5)

在HTML5中,爲了增強web的功能,提供了websocket技術,它不只是一種web通訊方式,也是一種應用層協議。它提供了瀏覽器和服務器之間原生的雙全工跨域通訊,經過瀏覽器和服務器之間創建websocket鏈接(其實是TCP鏈接),在同一時刻可以實現客戶端到服務器和服務器到客戶端的數據發送。
首先是客戶端new 一個websocket對象,該對象會發送一個http請求到服務端,服務端發現這是個webscoket請求,會贊成協議轉換,發送回客戶端一個101狀態碼的response,以上過程稱之爲一次握手,通過此次握手以後,客戶端就和服務端創建了一條TCP鏈接,在該鏈接上,服務端和客戶端就能夠進行雙向通訊了。這時的雙向通訊在應用層走的就是ws或者wss協議了,和http就沒有關係了。所謂的ws協議,就是要求客戶端和服務端遵循某種格式發送數據報文(幀),而後對方纔可以理解。跨域

科普

什麼是長鏈接、短鏈接?

在HTTP/1.0中,默認使用的是短鏈接。也就是說,瀏覽器和服務器每進行一次HTTP操做,就創建一次鏈接,但任務結束就中斷鏈接。若是客戶端瀏覽器訪問的某個HTML或其餘類型的 Web頁中包含有其餘的Web資源,如JavaScript文件、圖像文件、CSS文件等;當瀏覽器每遇到這樣一個Web資源,就會創建一個HTTP會話。
但從 HTTP/1.1起,默認使用長鏈接,用以保持鏈接特性。使用長鏈接的HTTP協議,會在響應頭有加入這行代碼:
Connection:keep-alive
在使用長鏈接的狀況下,當一個網頁打開完成後,客戶端和服務器之間用於傳輸HTTP數據的 TCP鏈接不會關閉,若是客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經創建的鏈接。Keep-Alive不會永久保持鏈接,它有一個保持時間,能夠在不一樣的服務器軟件(如Apache)中設定這個時間。實現長鏈接要客戶端和服務端都支持長鏈接。
HTTP協議的長鏈接和短鏈接,實質上是TCP協議的長鏈接和短鏈接。瀏覽器

Socket.IO

Socket.IO是一個徹底由JavaScript實現、基於Node.js、支持WebSocket的協議用於實時通訊、跨平臺的開源框架,它包括了客戶端的JavaScript和服務器端的Node.js。Socket.IO除了支持WebSocket通信協議外,還支持許多種輪詢(Polling)機制以及其它實時通訊方式,並封裝成了通用的接口,而且在服務端實現了這些實時機制的相應代碼。Socket.IO實現的Polling通訊機制包括Adobe Flash Socket、AJAX長輪詢、AJAX multipart streaming、持久Iframe、JSONP輪詢等。服務器

本文爲網上資料彙總+本身的理解
Socket.IO介紹:支持WebSocket、用於WEB端的即時通信框架
史上最全Web端即時通信技術原理詳解
知乎回答websocket

相關文章
相關標籤/搜索