歡迎分享:http:///contribute 最近工作中遇到一個(gè)場(chǎng)景,商家在商家后臺(tái)需要實(shí)時(shí)的獲取到有沒(méi)有新訂單,有的話(huà)是幾個(gè);這個(gè)需求類(lèi)似與日常中使用QQ或者微信時(shí)的新信息提醒一樣,只要有新信息就需要提醒;商家基本在PC上使用,各式瀏覽器都有:如 IE系列(7.0,8.0,9.0及以上),chrome內(nèi)核,firefox等;功能所屬的部署在Tomcat 6.0上,如果技術(shù)需要可以部署到 Tomcat 7.0上;
Ajax輪詢(xún)這是我們最自然想到的。 采用常規(guī)Ajax輪詢(xún)的方式,每10s或者30s輪詢(xún)一次,既可以判斷出有有多少個(gè)新訂單進(jìn)入,且這種時(shí)間間隔對(duì)于消息提醒也是可以接受的。這種技術(shù)方式實(shí)現(xiàn)起來(lái)非常簡(jiǎn)單,目前的機(jī)器都是可以機(jī)器的,前端瀏覽器也都支持。 但是這種方式會(huì)有非常嚴(yán)重的問(wèn)題,就是需要不斷的向服務(wù)器發(fā)送消息詢(xún)問(wèn),如果有1w個(gè)商家打開(kāi)了瀏覽器,采用10s輪詢(xún)的方式,則服務(wù)器則會(huì)承擔(dān)1000 的QPS,這1w個(gè)商家可能只有10個(gè)有訂單通知;這種方式會(huì)對(duì)服務(wù)器造成極大的性能浪費(fèi)。 還有一個(gè)類(lèi)似的輪詢(xún)是使用JSONP跨域請(qǐng)求的方式輪詢(xún),在實(shí)現(xiàn)起來(lái)有差別,但基本原理都是相同的,都是客戶(hù)端不斷的向服務(wù)器發(fā)起請(qǐng)求。 優(yōu)點(diǎn)
cometComet是一種用于web的推送技術(shù),能使服務(wù)器實(shí)時(shí)地將更新的信息傳送到客戶(hù)端,而無(wú)須客戶(hù)端發(fā)出請(qǐng)求,目前有兩種實(shí)現(xiàn)方式,長(zhǎng)輪詢(xún)和iframe流。 長(zhǎng)輪詢(xún)(long polling)長(zhǎng)輪詢(xún) (long polling) 是在打開(kāi)一條連接以后保持,等待服務(wù)器推送來(lái)數(shù)據(jù)再關(guān)閉的方式。 HTTP 和JSONP方式的長(zhǎng)輪詢(xún)把 script 標(biāo)簽附加到頁(yè)面上以讓腳本執(zhí)行。服務(wù)器會(huì)掛起連接直到有事件發(fā)生,接著把腳本內(nèi)容發(fā)送回瀏覽器,然后重新打開(kāi)另一個(gè) script 標(biāo)簽來(lái)獲取下一個(gè)事件,從而實(shí)現(xiàn)長(zhǎng)輪詢(xún)的模型。 XHR長(zhǎng)輪詢(xún)這種方式是使用比較多的長(zhǎng)輪詢(xún)模式。 客戶(hù)端打開(kāi)一個(gè)到服務(wù)器端的 Ajax 請(qǐng)求然后等待響應(yīng);服務(wù)器端需要一些特定的功能來(lái)允許請(qǐng)求被掛起,只要一有事件發(fā)生,服務(wù)器端就會(huì)在掛起的請(qǐng)求中送回響應(yīng)并關(guān)閉該請(qǐng)求??蛻?hù)端 JavaScript 響應(yīng)處理函數(shù)會(huì)在處理完服務(wù)器返回的信息后,再次發(fā)出請(qǐng)求,重新建立連接。如此循環(huán) 長(zhǎng)輪詢(xún)優(yōu)缺點(diǎn)優(yōu)點(diǎn) 客戶(hù)端很容易實(shí)現(xiàn)良好的錯(cuò)誤處理系統(tǒng)和超時(shí)管理,實(shí)現(xiàn)成本與Ajax輪詢(xún)的方式類(lèi)似。 缺點(diǎn) iframeiframe 是很早就存在的一種 HTML 標(biāo)記, 通過(guò)在 HTML 頁(yè)面里嵌入一個(gè)隱蔵幀,然后將這個(gè)隱蔵幀的 SRC 屬性設(shè)為對(duì)一個(gè)長(zhǎng)連接的請(qǐng)求,服務(wù)器端就能源源不斷地往客戶(hù)端輸入數(shù)據(jù)。 優(yōu)點(diǎn): 缺點(diǎn) Google 的天才們使用一個(gè)稱(chēng)為“htmlfile”的 ActiveX 解決了在 IE 中的加載顯示問(wèn)題,并將這種方法用到了 gmail+gtalk 產(chǎn)品中。Alex Russell 在 “What else is burried down in the depth's of Google's amazing JavaScript?”文章中介紹了這種方法。Zeitoun 網(wǎng)站提供的 comet-iframe.tar.gz,封裝了一個(gè)基于 iframe 和 htmlfile 的 JavaScript comet 對(duì)象,支持 IE、Mozilla Firefox 瀏覽器,可以作為參考。 我們常用的網(wǎng)頁(yè)版的gtalk就是這種實(shí)現(xiàn)方式,Google的開(kāi)發(fā)人員使使用一個(gè)稱(chēng)為“htmlfile”的 ActiveX 解決了在 IE 中的加載顯示問(wèn)題。 Comet實(shí)現(xiàn)框架CometDCometD 框架是基于 HTTP 的事件驅(qū)動(dòng)通信解決方案,使用了Bayeux通信協(xié)議,提供了一個(gè) Java 服務(wù)器部件和一個(gè) Java 客戶(hù)端部件,還有一個(gè)基于 jQuery 和 Dojo 的 JavaScript 客戶(hù)端庫(kù)。
CometD 與三個(gè)傳輸協(xié)議綁定在一起:JSON、JSONP 和 WebSocket。他們都依賴(lài)于 Jetty Continuations 和 Jetty WebSocket API。在默認(rèn)情況下,可以在 Jetty 6、Jetty 7、和 Jetty 8 中以及其他所有支持 Servlet 3.0 Specification 的服務(wù)中使用 CometD。 Atmosphere框架Atmosphere 是一種 Java 技術(shù)框架,它提供了一個(gè)通用 API,以便使用許多 Web 服務(wù)器(包括 Tomcat、Jetty、GlassFish、Weblogic、Grizzly、JBossWeb、JBoss 和 Resin)的 Comet 和 WebSocket 特性。它支持任何支持 Servlet 3.0 Specification 的 Web 服務(wù)器。 Atmosphere 提供了一個(gè) jQuery 客戶(hù)端庫(kù),該庫(kù)可以使連接設(shè)置變得更容易,它能夠自動(dòng)檢測(cè)可以使用的最佳傳輸協(xié)議(WebSockets 或 CometD)。Atmosphere 的 jQuery 插件的用法與 HTML5 WebSockets API 相似。首先要連接到服務(wù)器,注冊(cè)一個(gè)回調(diào)來(lái)接收消息,然后再放入一些數(shù)據(jù)。 PushletPushlet 使用了觀察者模型:客戶(hù)端發(fā)送請(qǐng)求,訂閱感興趣的事件;服務(wù)器端為每個(gè)客戶(hù)端分配一個(gè)會(huì)話(huà) ID 作為標(biāo)記,事件源會(huì)把新產(chǎn)生的事件以多播的方式發(fā)送到訂閱者的事件隊(duì)列里。 Pushlet 最后更新于2010年2月5號(hào),之后至今沒(méi)有再更新。 Cometd 和Atmosphere框架參見(jiàn)示例代碼 (https://github.com/brucefengnju/cometdatoms)。 comet實(shí)現(xiàn)要點(diǎn)不要在同一客戶(hù)端同時(shí)使用超過(guò)兩個(gè)的 HTTP 長(zhǎng)連接 服務(wù)器端的性能和可擴(kuò)展性 在客戶(hù)和服務(wù)器之間保持“心跳”信息 服務(wù)器端在阻塞讀時(shí)會(huì)設(shè)置一個(gè)時(shí)限,超時(shí)后阻塞讀調(diào)用會(huì)返回,同時(shí)發(fā)給客戶(hù)端沒(méi)有新數(shù)據(jù)到達(dá)的心跳信息。此時(shí)如果客戶(hù)端已經(jīng)關(guān)閉,服務(wù)器往通道寫(xiě)數(shù)據(jù)會(huì)出現(xiàn)異常,服務(wù)器端就會(huì)及時(shí)釋放為這個(gè)客戶(hù)端分配的資源。 如果客戶(hù)端使用的是基于 AJAX 的長(zhǎng)輪詢(xún)方式;服務(wù)器端返回?cái)?shù)據(jù)、關(guān)閉連接后,經(jīng)過(guò)某個(gè)時(shí)限沒(méi)有收到客戶(hù)端的再次請(qǐng)求,會(huì)認(rèn)為客戶(hù)端不能正常工作,會(huì)釋放為這個(gè)客戶(hù)端分配、維護(hù)的資源。 當(dāng)服務(wù)器處理信息出現(xiàn)異常情況,需要發(fā)送錯(cuò)誤信息通知客戶(hù)端,同時(shí)釋放資源、關(guān)閉連接。 websocketWebSocket是HTML5開(kāi)始提供的一種在單個(gè) TCP 連接上進(jìn)行全雙工通訊的協(xié)議。WebSocket通訊協(xié)議于2011年被IETF定為標(biāo)準(zhǔn)RFC 6455,WebSocketAPI被W3C定為標(biāo)準(zhǔn)。在WebSocket API中,瀏覽器和服務(wù)器只需要做一個(gè)握手的動(dòng)作,然后,瀏覽器和服務(wù)器之間就形成了一條快速通道。兩者之間就直接可以數(shù)據(jù)互相傳送。 WebSocket借用HTTP的協(xié)議來(lái)完成一部分握手。 GET /chat HTTP/1.1Host: server.Upgrade: websocketConnection: UpgradeSec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==Sec-WebSocket-Protocol: chat, superchatSec-WebSocket-Version: 13Origin: http:// 其中 Upgrade: websocketConnection: Upgrade 向服務(wù)器說(shuō)明這個(gè)是基于websocket協(xié)議的,服務(wù)器會(huì)返回 HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=Sec-WebSocket-Protocol: chat 表明連接已經(jīng)建立。 瀏覽器支持
References
更多優(yōu)質(zhì)內(nèi)容,歡迎安裝、使用《開(kāi)發(fā)者頭條》iOS、Android 客戶(hù)端。 體驗(yàn)地址:http:///download
|
|
來(lái)自: ycwu314 > 《架構(gòu)設(shè)計(jì)》