開了N個知乎窗口,標題都有(1 條消息),點開其中一個窗口的消息提示後,(1 條消息)消失,緊接著其他所有標題都會陸續更新,什麼技術?
HTML5有一個websocket功能,對於低版本瀏覽器是如何做到的?類似於這種技術對於大訪問量時服務端的負載大嗎?
是否有好的主動從伺服器端『push』信息到客戶端的技術?
看了一下知乎的做法,是每個 tab 建立一個長連接,以便獲得伺服器端的事件然後更新。簡單來說,知乎讓瀏覽器發起一個請求,然後瀏覽器自然會等伺服器返回。伺服器有意不返回,僅在有事件推送時返回,或者 30 秒超時時返回,這樣瀏覽器就可以把返回理解為推送了。
知乎的做法並不是最有效率的,因為每個 tab 都建立了一個獨立的長連接,如果用戶打開很多個 tab 就會佔用很多伺服器資源。更理想的做法是如果 tab 之間能夠建立通信,則應該共享一個長連接。
P.S. 我以前在百度做網頁版的百度 Hi,所以比較了解所有這些長連接的做法。當年也研究過 Facebook Chat 的做法,就是多個 tab 共享一個長連接的。
我之前從沒有發現這個細節,看了題目後,便用chrome自帶的控制台,研究了一下。
我發現,知乎在打開頁面後,js一直在與伺服器交互(可能是一個定時請求),因為頁面沒有刷新,我猜是ajax,可能為了減小伺服器的壓力,所以基本每30s一次
一旦有新消息,馬上回復。因為有新消息的時候時間一般不是30s。
localStorage改變時有個事件會被觸發這麼用:
window.addEventListener("storage",function(event){
},false);
demo:HTML5 Demo: Storage Events
或者不用storage事件只用localStorage也可以實現
每個頁面輪詢localStorage,只需要一個頁面發ajax建議看下http://socket.io 機制
高瀏覽器用websocket , 低級瀏覽器自動降級為comet / ajax 輪詢
至於weibo為什麼不用,制約於技術選型(PHP,無demon , 無非同步)低版本的瀏覽器,可以模仿一個長連接。
browser發起一個request,伺服器那邊去查有沒有新消息,沒有就暫時掛起該請求(不給回復),然後每隔一段時間y秒檢查一次,一旦有新消息,就finish這個request,一直沒有的話x分鐘後返回「無消息」的消息。
這樣的思路下,browser發起一個request,被伺服器掛起0-x分鐘,可以大大減少browser發起request的頻率,同時也能獲得近似於「即時」的回復(如果每30秒發起一個請求的話,消息延遲最大會是30秒)。我們做的網站前面的x=2,y=5,有新消息更新到memcache,每次查新消息是去通過memcache查有沒有消息。看了一下知乎,它的x應該是30秒左右。伺服器那邊不知道是不是這樣做的。
一旦一個新消息被讀了,肯定會發送一個請求到伺服器,把這條消息,設置為已讀。其他打開的tab的掛起的請求就可以及時返回某某消息已讀,然後前台js做一些相應的設置。
這個方法應該可以兼容所有瀏覽器。這應該是一種伺服器Push技術,可以看這篇文章:Comet:基於 HTTP 長連接的「伺服器推」技術一般的伺服器Push技術包括:
- Ajax輪詢,每隔一段時間發送一個請求;
- HTTP長連接(利用Ajax等),伺服器Hold一段時間後再返回信息;
- HTTP Streaming,通過iframe和&