2012年3月13日 星期二

筆記:[Gevent + Bottle] How to detect client disconnection

已使用了 bottle 這一個小巧輕便的 framework 一陣子
加上了 gevent 提供的 pywsgi server 功能之後
算是一定程度解決了想實作出的long-polling的功能
程式結構可以不用有太大的變更,也不用過度擔心 io-blocking 的問題


不過前一陣子卻苦於無法得知 client 與 server 之間的連線是否已經中斷
翻閱 api 文件,皆無法找到相關敘述
甚至還找到有人寫了一個 test-wsgi-disconnect 的專案
來說明gevent好像還不行 ... 囧rz


儘管如此
自己經過土法煉鋼還是發現其實只要直接送資料出去
就可以知道連線是否還存在
但是這樣的作法,實在有點小蠢
無奈之下,還是決定爬一下 bottle.py 以及 pywsgi.py 的 code 
了不起就乖乖從 socket 面解決問題
爬 code 過程中,意外發現了這個 solution




之後我 trace pywsgi.py 後發現有這麼一行:

514 env['wsgi.input'] = self.wsgi_input

因此一切就迎刃而解了:


solution here:

 58     import select
 59     socket = bottle.request["wsgi.input"].rfile._sock
 60     time.sleep(10)
 61     r, w, e = select.select([socket],[],[socket], 0)
 62     if r or w:
 63         print "detect disconnect"
 64     else:
 65         print "not detect"

     Done !!


#2012.09.03 補充:
如果在 59  行之前使用過 bottle.request.body.buf 類似的方法來讀取 HTTP POST 的資訊
那麼 59 行就有可能出現錯誤(無 rfile 此屬性)
原因我推測應該是因為 bottle 的 framework 順手拿掉了不必要的屬性






沒有留言:

張貼留言