以前的一個項目,狀況以下: java
頁面使用Ajax定時刷新一次,每次刷新就到後臺中查詢比對,若是數據有變化,則刷新,更新數據,可是沒變化得話也會刷新一次,因此這很糾結。。。 web
如今想作成從後臺推送的效果: 瀏覽器
若是後臺數據有變化,就把數據推送到前臺,頁面數據更新,不然,不變化! 服務器
B/S架構中服務器向瀏覽器推送數據在不少場合都有需求,好比實時的監控報警、實時的調度,等等。凡是對實時性要求越高的場景,越是須要服務器及時、準確地向瀏覽器推送數據。這裏咱們就討論一下在B/S架構下,能夠實現從服務器向瀏覽器推送數據的幾種技術及其相應的特色。 websocket
基於HTTP協議
1. HTTP協議的特色
純的HTTP協議在本質上是無狀態、無鏈接的,它基於請求/響應的工做模式,使得瀏覽器在每次發生請求的時候和服務器創建鏈接,當接收到響應的時候斷開鏈接;在這種狀況下,要讓服務器主動向瀏覽器發送數據是不可能的。
技術老是爲需求服務的,在不少瀏覽器須要及時獲取服務器數據更新的須要下,技術人員們變通地發明了一些基於HTTP協議的「僞」長鏈接技術,實現了服務器數據向瀏覽器的「準」推送。
2. 定時刷新
定時刷新是最粗糙的實現快速感知服務器數據變化的方法,原理就是不停地刷新頁面從而顯示最新的服務器端數據。定時刷新從技術上大致有兩種實現方法:一是經過HTML的META標籤設置頁面刷新間隔,好比如下的標籤會在瀏覽器中每隔5秒刷新當前頁面:
架構
5秒以後刷新本頁面: <meta http-equiv="refresh" content="5" /> 5秒以後轉到夢之都首頁: <meta http-equiv="refresh" content="5; url=http://www.dreamdu.com/" />
這種方式會看到頁面有明顯的刷新,用戶體驗會比較差;與此相對應的另一種方式就是AJAX,在JavaScript腳本中添加一個定時器,每隔必定時間向服務器發送一個AJAX請求,獲得響應之後去更新頁面的內容。如下JavaScript代碼會每隔10秒發送一個AJAX請求去更新當前頁面的部份內容:
setInterval(function(){sendAJAXRequest()},10000); socket
如圖 1是定時刷新的模型圖: 函數
定時刷新這種模式至關於一個下級每隔一段時間打電話給上級,請示當前指示。固然,若是在這個時間段內發生了一些狀況,他們之間是沒辦法溝通的,因此信息並非「實時」的;另外,刷新間隔到底設置多少合適也是個問題,服務器的負擔也比較大。 性能
3. 輪詢
輪詢也是經過AJAX進行的,它與AJAX定時刷新的區別僅在於接收到AJAX響應之後的工做。定時刷新徹底是瀏覽器主動的,在瀏覽器和服務器之間存在必定的斷開間隔;而輪詢這種方式會在AJAX響應中再次發送AJAX請求,也就是說當響應結束,瀏覽器和服務器之間一旦斷開鏈接的時候,瀏覽器會再次發送請求創建鏈接。 ui
輪詢這種模式至關於一個下級不停給上級打電話請示,上級指示下達之後掛了電話,下級可能去執行指示或者不執行,可是隨即下級將再次給上級打電話繼續請示。這種模式能夠保證數據更新比較實時,可是服務器負擔也是一個問題。
順便提一下,輪詢這種模式通常會在瀏覽器的XMLHttpRequest的readyState爲4(響應數據傳輸結束)的時候調用回調函數,此時鏈接已經關閉;可是在Firefox中支持Streaming AJAX模式,也就是XMLHttpRequest的readyState爲3(響應數據仍在傳輸)的時候調用回調函數,此時鏈接還沒有關閉。
2. Java消息服務(JMS)
JMS是一組公開的Java API,它定義了與消息相關的接口和語義,目前JMS已經成爲J2EE中的重要組成部分。
當有客戶端鏈接到JMS服務器的時候,JMS的鏈接工廠會根據鏈接類型來建立一個虛擬鏈接,這個鏈接會具體負責消息的傳遞;在這個鏈接創建完成後,會產生一個會話,會話中保存了消息生產者或消息消費者的信息;消息的消費者會對感興趣的消息目的地(隊列或主題)創建一個監聽,消息的生產者則負責把消息發送到這個目的地上。
另外JMS還有一些值得一提的特色,好比支持事務性會話、能夠設置消息的持久性、設置消息的優先級、容許消息過時、能夠構建長期訂閱等。這些特性在各類企業級應用環境下都有可能提升應用的功能或性能。
實現JMS的商業中間件有IBM MQSeries、BEA WebLogic JMS等;開源中間件有OpenJMS、Apache ActiveMQ等。
3.websocket