淺談 Comet PUSH Server 架構
HTTP 統治網路界
簡單來說,一般的 Socket Programming 都是保持一個雙向的連線,可以送可以收。但是 HTTP Design 為了以下理由,設計方向為單向的。
- 提高 Server 處理效能
- 方便作 cache,Proxy 容易融入
- 方便作 Server Farm
- 網路發展初期,實體硬體狀況不佳,很容易造成 connection lose,單向傳輸可以有效避免瞬斷
如果以 HTTP 當初設計的初衷「文件交換」來看,我們發現到他設計的非常的好,也相當成功的在當初糟糕的網路環境下成功的生存下來。但是就是因為 HTTP 設計太成功了,導致現在網路業者一股腦兒將各式各樣的 App 放在 HTTP 的架構上,想要用當初只是為了文件交換的協定,變成一個包山包海的協定,自然產生很多問題。
HTTP 最大的問題在於即時性。
要解決 HTTP 的即時性的問題,有 Polling 跟 Server PUSH 這兩種方式。
Polling
我們想要做到即時傳訊,Server 端觸發 Client 事件等等功能,以現行的 HTTP 架構下,都得利用 Polling 的方式來做到。Polling 其實也就是現在的 RSS Reader 的作法,RSS Reader 會每過半個小時,或是一個小時去問對方 Server 有沒有新文章。用 Polling來作即時性的功能,最大的好處在於容易寫,因為他完全符合 HTTP 的架構,但是最大的壞處在於不夠即時。以 RSS Reader 來說,每過一個小時去問有沒有新文章,代表的意思就是有一整個小時的空窗期,你得每過一個小時才知道有沒有新文章。
以 RSS Reader 的屬性來說,採用 Polling 有很多好處
- 我其實不需要知道立刻知道有多少新文章,使用者對於 RSS 的即時性需求沒那麼高
- Blog 系統多變,與其設定一個各 Blog 系統共通的 Socket 協定,不如設定一個共通的文件交換格式來的簡單
因為 Polling 在某些地方不是那麼的好,所以才有 Server PUSH 機制出現。
Server PUSH
Server PUSH 是建構在建立一個不中斷的 Socket Connection 下面。一個作法是使用 iframe ,送出的header中要把content-type設為” multipart/x-mixed-replace”,來保持一個不間斷的 HTTP Connection。另外一個作法就是用 Flash 來跟 Server 建立一個 xmlsocket。保持一個不中斷的 Connection ,代表 Server 有新訊息就可以直接傳給 Client,不用等待 Client 過來 request。
這樣可以帶來的好處就是,Server 有狀態更新才會有網路傳輸,如果沒有狀態更新,就不會浪費資源。而 Polling 是不管有沒有狀態更新,都得花上固定的網路傳輸成本,當然就會比較浪費資源。
舉個例子,考試成績快出來了,你每個小時都從宿舍去公佈欄看成績出來了沒,假設成績沒那麼快出來,你自然會花上許多無意義的時間在宿舍到公佈欄之間的往返上面( Polling )。但是如果老師有你的手機(不斷線的 Connection ),成績公佈老師就打電話給你,告訴你的成績(Server Push)。這樣不是好多了嗎?
但是你會問,假設老師打電話給你,你在收不到訊號的地方怎麼辦?假設班上人數太多,老師不是就會打電話打到手軟?
這剛好講到 Server PUSH 的壞處,第一個壞處是假設 Client 網路不好,connection 造成瞬斷,那麼你的訊息就會消失不見了。另外一個壞處就是,持續性的 connection 很難做到 Load Sharing機制,通常大家都只會跟同一台 PUSH Server 作連接,這台 PUSH Server 在人一多就會產生大負載度的問題。這當然有辦法解決,只是這就已經要討論到很深的地方了。
雖然 Server PUSH 不是萬能的。不過整體來說,以傳遞「即時性需求高的訊息來說」,PUSH Server 帶來的好處絕對會比 Polling 來的好,這倒是無庸置疑的。