2011-02-12 186 views
3

我需要創建一個Python中間件,將做到以下幾點:Python的Web服務器:如何以服務請求異步

一)接受HTTP GET /來自多個客戶端post請求。

b)修改並將這些請求分發到後端遠程應用程序(通過套接字通信)。我無法控制這個遠程應用程序。

c)從後端應用程序接收處理結果並將這些結果返回給請求客戶端。

現在,客戶端正在期待同步請求/響應場景。但後端應用程序不會同步返回結果。也就是說,一些請求比其他請求花費更長的時間來處理。因此,

客戶端1:發送HTTP請求C1 - >得到響應R1

客戶端2:發送HTTP請求C2 - >得到響應R2

客戶端3:發送HTTP請求C3 - >得到響應R3

Python中間件以某種順序接收它們:C2,C3,C1。將它們按此順序分發到後端(作爲非http消息)。後端以混合順序R1,R3,R2響應結果。 Python中間件應該將這些響應打包回http響應對象中,並將響應發送回相關的客戶端。

是否有任何示例代碼來編程這種行爲。似乎有20個不同的python網絡框架,我很困惑,哪一個最適合這種情況(會喜歡儘可能輕量級的東西......我會認爲Django太重了......我試過瓶子,但我不確定如何去編程這個場景)。

============================================== ==

更新(基於下面的討論):請求有一個請求ID。響應有一個響應ID(它應該匹配它們對應的請求ID)。中間件和遠程後端應用程序之間只有一個套接字連接。雖然我們可以維護一個{request_id:ip_address}字典,但問題是如何構建一個HTTP響應對象給正確的客戶端。我認爲,線程可以解決這個問題,每個線程維護自己的響應對象。

+0

您基本上需要一種方法來識別後端響應,以便您可以將其轉發給正確的客戶端。如果這是正確的,那麼您需要進一步解釋中間件後臺通信是如何發生的。你是否使用每個請求的套接字或單個套接字?有什麼樣的信息可以用來區分迴應? – jweyrich 2011-02-12 18:11:29

+0

感謝您的評論。中間件使用一個持久套接字連接到後端。所有來自中間件的請求都通過這個單一套接字轉發。客戶確實會發送一個請求ID和他們的請求。響應ID應該與請求ID匹配。所以問題依然存在:中間件(Web服務器)如​​何跟蹤哪個請求ID屬於哪個客戶端?我的意思是,有沒有辦法讓中間件中的cgi腳本創建像這樣的元組的數據庫,並且一旦響應id匹配,然後發送一個http響應給clientip:clienttcpport? – 2011-02-12 20:13:23

回答

2

引用您的評論:

中間件採用了單一的持久套接字連接到後端。所有來自中間件的請求都通過這個單一套接字轉發。客戶確實會發送一個請求ID和他們的請求。響應ID應該與請求ID匹配。所以問題依然存在:中間件(Web服務器)如​​何跟蹤哪個請求ID屬於哪個客戶端?我的意思是,有沒有辦法讓中間件中的cgi腳本創建一個元組數據庫,並且一旦響應id匹配,然後發送一個http響應給clientip:clienttcpport?

在中間件中完成所有這些處理是否有任何特殊原因?如果更合適,你應該可以在裝飾者或其他地方完成所有這些工作。

無論如何,您需要維護一個全局並行字典(擴展dict並使用threading.Lock來保護它)。在發出新請求時,將給定的請求標識存儲爲密鑰,並將其關聯到相應的客戶端(發件人)。每當你的後端響應,從這個字典中檢索客戶端,並刪除條目,使其不會永久累積。

UPDATE:有人已經爲您擴展字典 - 請檢查this answer

3

螺桿框架。這正是asyncore的那種任務。該模塊允許基於事件的網絡編程:給定一組套接字,當數據準備就緒時,它會回調給定的處理程序。這樣,線程不需要只是傻傻地等待一個套接字上的數據到達並痛苦地將它傳遞給另一個線程。你將不得不自己實現http處理,但是可以在其中找到示例。或者,您可以使用uwsgi的異步功能,該功能可以讓您的應用程序與現有的網絡服務器集成,但默認情況下不與asyncore集成---儘管它不會很難使其工作。取決於具體的需求。