在2008年底,我突發奇想的開始做了一個名為「拓客基地」的網站,這是一個聊天室網站,大約在2009一月底完成一個簡易的beta版,但卻在辛辛苦苦做完之後一直擺著沒去裡它,也從未對外公開它的網址。
與一些聊天室不同的是,這個聊天架構不是由Client(Browser)不斷送出Request,而是由Server在有需求時才送出訊息或通知。
直到最近pigo大在他的部落格中提到一種叫做Comet架構的概念,我才發現原來有這樣一種架構概念,在這之前我倒是沒有聽過,真是後知後覺啊。
在稍微了解過這種概念後發現與我當初想的好像頗為相似,重點似乎都是Server的主動,而不是不斷的請求,但我不是很確定是否有何不同,不過很恰巧的是Server端都是用C#寫的(硬要攀關係 XD)。
仔細想想這樣的運作架構或許有它的存在的價值,重點在於用在什麼地方。
因此今天又重新把這個網站整理一下搬了出來,有興趣的人不妨隨意玩玩,或許可以激起你另一個想法。
Screenshots
Web 聊天介面
室長端介面
網址:
帳號:test 密碼:test
概念
這個聊天室架構不是由Client(Browser)不斷發送Request請求,而是讓聊天室成員與室長端建立一個固定的連線,換句話說是在有需求時訊息才會被傳遞,而室長端就是一個Server端,訊息流量都由使用者(室長與成員)自行承擔,缺點是使用者如果要當室長必須需要下載一個Client端軟體。
在這樣架構之下總共會有兩種Server端(HTTP Server不納入計算),一是中介Server,用於室長與聊天成員之間建立連線的媒介,處理一些狀態訊息等等,二是室長端。
但事實上,中介Server的角色在某些應用底下,它並不是一定要存在的,因此若單指聊天室長端的Server與聊天成員的運作來看,這樣的運作就會很像所謂的comet(希望我沒有會錯意)。
由於是固定連線的關係,因此在訊息的傳遞上非常即時,實測的結果,室長端使用一般家用網路其即時的效果跟MSN似乎不相上下,當然這取決於連線數量的多寡與頻寬條件。
如下簡圖:
圖示來自:
http://www.vistaicons.com/icon/i161s0/web_browsers_icons.htm
關於comet架構
這有一些文章可以參考:
- http://lightyror.thegiive.net/2007/06/comet-push-server.html
- http://www.pigo.idv.tw/archives/761
- http://blog.roodo.com/rocksaying/archives/12010463.html
PS. pigo大最近打算釋出他的原始碼,有興趣的人不妨留意一下他的消息。








四月 7, 2010 at 2:23 上午
有很多 Comet 的做法
最複雜 , 效能最好就是實作 HTTP Server , 直接將程式邏輯寫在 Server 中
當然我若有心力會去實作看看
而我現在做的 CxServer 概念是把 CxServer 當作一種模擬 TCP/IP 的中介 Proxy 角色
CGI 之間可以傳遞訊息 , 訊息內容由程式設計師自訂 , 例如用最簡單的 serial 和 unserial 就可以了
每個 CGI 和 CxServer 之間會有所謂的階段(Session) , CxServer 會給 CGI 一組 Session Key , CGI 之間就是靠 SessionKey 作 Send , Recevie 的動作而已
不清楚你這個 chat 的架構是如何 , 搞不好和我很類似耶
四月 7, 2010 at 6:02 上午
我的方法是透過 Flash Socket 建立 TCP 連線,因此Server的實作上相對就簡單多了,只是簡單的接收與傳遞訊息,之間交換訊息的格式則是以XML自訂的,基本上我是寫死的
照你的說法聊天的過程中會與HTTP Server有關係,但我的作法於聊天的過程中不會經過HTTP Server(瀏覽器載入Web聊天介面不要算的話),因為直接透過室長端進行傳遞訊息
你的實作方法看起來很棒,似乎是一種很有彈性的方式,CxServer 似乎可以通用於任何一種應用?
非常期待大作!!
四月 7, 2010 at 10:20 上午
原來是 Flash Socket 啊 , 那這樣和 Comet 概念不同
我有看過 javascript 版 socket , 但它是載入 flash 的 socket 物件來做的的 . 本來想玩玩 , 但我很怕 Server 端寫不好容易被攻擊 …… 所以我就沒做了 … 哈
四月 7, 2010 at 11:41 上午
哦!原來如此,那請問這中間有和差別嗎?概念不一樣?
四月 7, 2010 at 12:56 下午
Flash Socket 是走真正的連線不中斷 , 但前提是browser 要支援 Flash
Comet 仍是走 HTTP 協定 , 但不斷線 , 有事件發生時 Push 出資料 , 所以看起來是即時
以 Facebook 的聊天功能就是一直連線 ,有對話來的時候 , 就馬上收到 , 此時原本的連線又斷掉重連 , 因為 Facebook 是用 xmlhttprequest 實作 , 所以必須有資料來就重連 , 畢竟 xmlhttprequest 只能收資料 , 不能單行執行 java script
我的網站上的 demo 採用 iframe , 可以維持一段時間一直Push資料不用重連
這一段時間 , 假設每秒都有資料都送出一行 script , 那麼瀏覽器就會去執行 , 所以更即時
當然缺點就是你所看到會有 browser loading 的狀況 , 這是瀏覽器對 iframe 尚未將資料收完的情形處理
所以基本上差別就是 Comet 是走既有 HTTP 傳輸技術的偽即時連線
四月 7, 2010 at 1:08 下午
原來如此,所以他仍然走HTTP協定,但是卻想辦法去hold住連線,這麼說來果然能夠實作一個簡易的HTTP Server會是最好的辦法,但那太費時費力了,你現在的辦法是個聰明的好辦法,受教了,謝謝
不過話又說話來,以Flash目前的普遍性來說,而且甚至可以做到P2P,也是個不錯的解決之道,雖然他不是走標準的規範
四月 7, 2010 at 1:57 下午
Flash Socket 很好啊 . 但難度是在 Server 端及 Client 端都要寫得很好
HTML5 也有 WebSocket , 等過一陣子 , 也許又是另一種技術的改朝換代了
但是都有一個大問題存在 , 就是提供 Socket 服務的 Server 就是被攻擊的目標了
如果沒有三兩三…一下子就被玩掛了
四月 7, 2010 at 2:16 下午
對,WebSocket也是個不錯的選擇,但瀏覽器的支援似乎還不佳,被攻擊又是另一個問題了 XD
四月 13, 2010 at 12:22 上午
非 http 的問題是無法穿越防火牆…
四月 13, 2010 at 1:03 上午
有沒有什麼見解或想法呢?
五月 1, 2010 at 4:22 下午
應該是可以的
把 port 設為 80 就可以
再不行就是模擬成 http 封包以規避 layer7 的檢查
但如果模擬成 http封包 , 那又跑回 comet 架構了 哈 !