2012/03/04

實現網頁即時傳訊 Web instant message (IM)

最近想弄一個Web IM,在web上做即時聊天有一定的困難,因為受限在http協定原生的特性:
client:request -> server:response -> 結束
傳輸一定要從client開始,而且一來一往誰也不能多,想做到server push有一定的難度,不像tcp raw socket自由度那麼高。


早期的聊天室會使用polling的方式定期 refresh (post back) 來更新頁面,同步的時間取決於refresh的頻率,但server loading也隨著頻率上升而增加。後來有了Ajax,頁面更新不用再一直閃爍,但還是有原本耗資源的問題。

近期較廣泛被使用的是Ajax搭配long polling,做到省資源又可以與server同步的效果。
Polling就是client定期的發request,long polling就是定期發request,但server不馬上response,而是等到有需要的時候再response (例如有人傳新訊息給你時),通常browser timeout都蠻長的,所以這段等待的期間相對polling就很省資源。如果還不是很懂,可以參考這一篇:Browser 與 Server 持續同步的作法介紹

要做到long polling這個效果需要server support,server必需要把request object先keep住,等到有需要的時候再抓出來回應給client。用Tornado來舉例,就是RequestHandler被call時,先把Handler存起來,等到時機到了再執行finish() function。


下面列出幾種IM的 model,我想實現的是最後一種 ── 跨平台而且server可以隨著loading scale-up。



多人聊天
也就是基本款,這用Tornado source code 裡面的 demo: chat 就可以做到了

一對一
可以從上面的範例去改。把username與user自己的request(connect) bind在一起,彼此傳訊時指定username,反查到對應的request object就可以把訊息帶回去。
若要支援離線訊息,則需要用database之類的先把資料keep住,等到對方上線時再帶回去。



跨平台
不只網頁可以聊,還可以跨到iOS與Android平台。Ex: facebook messenger
Smart phone上的solution:
1. 在smart phone裡面塞web view
2. 在smart phone裡一樣發http request
3. 搭配push notification service
    a) iOS: APNS
    b) Android: C2DM


Scale-up
隨著人數上升勢必會遇到擴充的問題,使用多台主機時,sender與consumer可能會連在不同server上,server間需要額外的溝通方式或媒介:
1. 找出對應的主機然後forward message過去

2. 用database, memcache, message queue當媒介



我把腦中的想法一步一步列出來,之後慢慢來實現它。



沒有留言:

張貼留言