Comet (Server Push) on Turbogears (2)

上一篇提到了Comet,以及Turbogears

Turbogears是用Python實做的一套Web development framework,有點像Ruby on Rails那樣,可以讓人用Python快速建構web application。這個framework包山包海,一般web app需要用的東西全都有,而且也很容易上手。我一連用它作了2個project,都很愉快的解決掉,直到最近要作即時性非常重要的web game,才發現我需要有server主動送出資料給client的能力。

我根據Server Push and Server SocketsXMLHttpRequest兩篇reference,在Turbogears上實做出一個簡單的Cometdecorator。這個decorator可以非常方便的在Turbogears中(其實只要用CherryPy就可以了),加入支援Server Push的method。大致上的作法是這樣子的。Turbogears底層所用的CherryPy可以藉由回傳一個generator來分段傳回結果,進而達到HTTP streaming的功能。但只有這樣還不夠,我們得改變CherryPy回傳的Content-type為"multipart/x-mixed-replace",並且在每個片段前後都包上multipart delimiter。Python 2.4後有了一個很棒的新功能: decorator,可以在任何一個function/method上包上另一個function,例如:[code lang="python"]def wrapper(f):def _wrapper():return "< < " + f() + " >>"return _wrapper@wrapperdef func():return "Hello world"print func() # The result is "< < Hello World >>"[/code]上面這個例子,利用decorator在func()的結果前後加上了新的文字,但卻不用更動func()以及主要的程式碼。所以,decorator可以很方便地在不更動其它code的前提下,在現有的function上包覆上新的功能。如果對decorator有興趣的,可以參考Python 2.4 Decorators這篇文章,裡面詳細介紹了decorator及其應用。一開始提過,我正在作一個web game,第一個碰到的麻煩就是玩家們必須等其它玩家到齊,遊戲才能開始。在沒有server push的技術前,我是在前端用JavaScript的setTimeout()加上Turbogears(其實是Mochikit)的loadJSONDoc()不斷地去polling,問到server回應人已經到齊為止。利用decorator的優點,我寫了一個comet decorator,可以讓Turbogears(CherryPy)的user們輕易地加上server push(Comet)的能力。 使用方法如下:Server side(Turbogears):[code lang="python"]from Comet import cometclass Root(controllers.RootController):@expose()def comet_wait(self):@comet(content_type='text/plain') # content_type can be omitteddef _waiting():yield "waiting..."time.sleep(5) # replace me with real codeyield "start"return _waiting()cherrypy.config.update({'/comet_wait':{'stream_response':True}})[/code]Client side(Javascript):[code lang="javascript"]function handler(evt){logDebug("onLoad handler");var t = evt.target.responseText;$('msg').innerHTML = t;}var req = new XMLHttpRequest();req.multipart = true;req.onload = handler;req.open("GET", "/comet_wait", true);req.send(null);[/code]上面這個例子模擬了user等待server通知遊戲開始。我在Root下加了一個comet_wait method(相對的URL為http://SERVERNAME/comet_wait),並把stream_response設為true,讓這個method可以分段傳回資料。這裡的關鍵在generator method _waiting()前加上的@comet(content_type='text/plain'),這個decorator會把HTTP response的content-type設為"multipart/x-mixed-replace",並且讓_waiting()每次用yield傳給client的結果前後都包上multipart delimiter。在client端,因為Mochikit不支援multipart的AJAX request,所以只好自己土法煉鋼一下。我們用XMLHTTPRequest打開一個不中斷的channel,等待server通知遊戲開始。為了要配合server的multipart data,我們必須把req.multipart設為true,並把req.onload設為每次有資料進來時的handler。到此,就完成了一個簡單的Comet client和server。server一開始收到client的request後,會先發出"waiting..."的訊息,接著等待5秒後,再主動送出"start"的訊息。這中間的time.sleep,可以換成檢查玩家是否到齊的程式,而client只要在onload handler裡檢查遊戲是否開始就行了。完整的Turbogears example和comet decorator的實做下載:閱讀全文

網頁瀏覽加速

剛看到網頁瀏覽加速法這篇文章,發現原來Firefox暗藏HTTP pipelining的選項,而且預設是關閉的..XD所以一般使用者,其實只要在Firefox的網址列輸入about:config,再把network.http.pipelining設成True,就可以大幅提昇瀏覽網頁的速度。既然Firefox可以加速,那Safari呢?很不幸的,Safari不支援HTTP pipelining (啊啊啊~ 怎麼會這樣...) 雖然得知這個消息有點可惜,但我也在搜尋過程中意外發現一個加速Safari的方法,只要在終端機(Terminal)下面輸入這個指令:defaults write com.apple.Safari WebKitInitialTimedLayoutDelay 0.25這個設定可以讓Safari在真正讀取完網頁前,只delay 0.25秒就把網頁顯示出來。因為這個設定的預設值本來是1秒,所以只要改了這個設定,就會感覺到Safari載入的速度變得飛快無比(非常明顯,比Firefox的HTTP pipeling還要爽XD)。Safari愛用者,快快改變這個設定吧!閱讀全文

Vim + Visual Studio .NET on Windows

像我這種用習慣vim的人,不論用甚麼其他的編輯器都會渾身不對勁,更別提還要拿來寫程式。因此我排斥Visual Studio已經不是一天兩天的事了,但這學期修了個Game Programming,很不幸的它提供的Game Engine只能在Windows下跑...這讓我不想用Visual Studio也不行了 :((呃,我知道MinGW啦,但我並不想花太多力氣搞MingGW+DirectX+Game Engine的相容問題...)所以呢,我得在Windows上裝vim,然後讓我能在vim中compile & test程式。以前的Visual Studio可以用一個叫VisVim的plugin,但VS .NET後就不能用了。另外,以前還能export makefile出來,現在似乎也不行了...!#*(!#&!&%@$研究了半天,發現我得透過"Microsoft Visual Studio .NET 2003/Common7/IDE/DevEnv.com"這個程式,才能在command line底下build program。底下是給vim的設定,我把這個設定加在vim的session file中,這樣之後再開project就不用一直重設,而這個設定也不會干擾到其它檔案了。set makeprg=devenv.com /Build Debug xxx.slnset errorformat= %#%f(%l) : %#%t%[A-z]%# %m(xxx.sln請自行換成你的.sln檔。DevEnv.com的PATH也要先設好。)這樣就能在vim下用:make來build程式,並且vim也能parse錯誤訊息並自動跳到對應的那一行了。只是有一點我還搞不定,devenv的help說用/LCID能設定它的locale,但我怎麼設都沒用,跑出來的訊息一直都是中文的,這讓我在UTF-8 term下面老是看到一堆亂碼..。閱讀全文

人體搜尋引擎 Ms. Dewey

Ms. DeweyMs. Dewey是一個很有意思的搜尋引擎, 它不像傳統的搜尋引擎, 一進去只有一個冰冷的文字輸入框,而是一位正在翻動手中雜誌的美女。這很像The Time Machine中出現的未來資料庫,會跟人對談、互動,也就是一個活生生的人體搜尋引擎。Ms. Dewey目前雖然還只是用文字來呈現搜尋結果,但用這種方式來設計網站的介面還真是很有創意 :-D閱讀全文

Windows Vista on Mac Mini

Vista screenshot剛才在實驗室的Intel Mac Mini上測試了Windows Vista RC1這裡可以下載),Aero Glass的效果在Mac Mini的Intel 945GM上跑得出來,於是整個畫面都是透明的視窗和動畫效果,速度也還不錯。至於實用上的感覺.... 呃,老實說,我覺得動畫多得有點噁心。每個視窗都會放大+淡入「蹦」出來,或是縮小+淡出再關閉。雖然剛看到真的還蠻炫的,但看久還蠻容易累的。這很像最近在Linux上很紅的XGL, 為了炫而炫,但卻沒有考慮到實際上長時間用起來的感覺。雖然Vista有點中看不中用,但還是有些不錯的改進,例如按alt-tab時出現的視窗列表終於可以用滑鼠選了..(嘿,這當然是從MacOSX來的功能XD)。BTW,因為Mac Mini內建的硬碟實在太小了,所以我是把MacOSX整個裝到用1394接的外接硬碟上 ,而內建硬碟裡分別裝了WinXP和Vista。(很可惜的是,Windows似乎沒辦法裝到外接硬碟上開機..@@)閱讀全文

專心模式

剛從LifeHacker看到一個有趣的軟體:JediConcentrate它可以把除了正在focus的視窗外,全部都變暗,就像是Mac下的Exposé的效果一樣。這麼做可以讓你把注意力在前景的程式上,暫時忽略雜亂的背景視窗和畫面。在Mac下也有同樣功能的軟體,叫做Doodim,如果想讓自己在電腦前能專心點的人可以試試看 :-D10/11 Updated:jclin提到有另一個小巧的軟體:Ghoster也有同樣的功能, 看起來也是個不錯的選擇 :-D閱讀全文