[英]Delphi 7 Indy 9 multithreaded HTTP Server
我需要編寫一個多線程HTTP服務器。 我知道Indy通過IdThreadMgrPool處理線程。
我的要求很簡單:擁有一台服務器,它可以接受多個並發客戶端(Web瀏覽器POST請求),運行有限數量的調用Delphi DLL的線程(可能與連接線程分開),並返回結果。
無阻塞將是最終的選擇(例如node.js)。
關於此主題有幾篇SO帖子。 我在這里(或通過Google)找不到的是如何使用IdThreadMgrPool的示例。 我看到有帖子說必須使用它,但沒有示例如何使用。 在Indy的網站上也沒有任何示例。
有人可以指出一個例子嗎? 還是有一個FOS框架對此適用?
一種想法是讓Indy正常產生多個線程,然后讓這些線程訪問運行DLL的受控線程池。 如果這是合理的話,那么我只需要知道“正常”案例用法示例即可。
要使用TIdThreadMgrPool
,至少要做的就是創建一個實例,將其分配給TIdHTTPServer.ThreadMgr
屬性,並設置其PoolSize
屬性。 所有這些都可以在設計時完成。
請記住, PoolSize
不會限制服務器上的連接數。 服務器為此具有自己的MaxConnections
屬性。 例如,您的PoolSize
為10,同時連接了15個客戶端,因此有15個線程在運行。 當它們斷開連接時,會將10個線程放回池中,並終止5個線程。
若要自定義池線程,可以從TIdPeerThread
派生一個新類,可以選擇重寫其虛擬的BeforeExecute()
和AfterExecute()
方法以執行每個線程的初始化清理,然后將該類分配給服務器(而不是ThreadMgr的) ThreadClass
激活服務器之前在運行時添加屬性。 然后,在服務器事件處理程序內部,可以將提供的TIdPeerThread
對象轉換為自定義類,並根據需要使用它。
您可以將方法添加到自定義線程類中,並使它們在內部訪問DLL,並根據需要進行限制。 最簡單的限制是使用單個共享信號量來控制一次可以進入該信號量的線程數。 因此,即使正在運行15個線程,也可以一次限制為2個線程。
因為您說要“在線程中運行DLL”,所以信號量可能還不夠。 在這種情況下,我建議改用I / O完成端口 。 您可以讓您的自定義線程類使用PostQueuedCompletionStatus()
將請求發布到IOCP,然后等待響應返回。 節流由您創建的為IOCP服務的線程數來完成,例如每個CPU內核一個線程。 每個IOCP線程將在循環中使用GetQueuedCompletionStatus()
來接收發布的請求。
Indy不是異步的,因此您將無法將請求發布到IOCP,並使其在准備好后直接將響應發送回客戶端。 服務器使用管理客戶端連接的相同線程將響應發送回客戶端。 因此,客戶端線程將必須向IOCP發送請求,並等待其響應,然后將該響應發送給客戶端。 您可以定義一條包含TEvent
,記錄調用DLL所需的輸入值以及DLL響應的輸出值的記錄。 然后創建該記錄的實例,將指向它的指針發布到IOCP,然后等待TEvent
發出信號。 當IOCP線程接收到記錄指針時,它可以根據需要調用DLL,用響應填充記錄,然后用信號通知記錄的TEvent
。 等待中的客戶端線程將被解除阻塞,並可以根據需要將記錄的響應數據發送到客戶端。
Indy服務器無法很好地擴展。
考慮使用基於iocp的http.sys內核模式服務器。
我們的開源SynCrtSock單元具有高性能的http服務器,並且可以在Delphi 5到XE6上完美運行。
例如,參見此示例代碼 。
如果您有可用的Windows服務器,建議您使用Delphi 7編寫ISAPI DLL並將其部署在IIS上,這將處理所有服務器端問題,尤其是當您使用帶有IIS 7.5(或更高版本)的Server 2008 R2時。 您的客戶端可以使用Indy連接到IIS,並且Indy客戶端與Delphi ISAPI的請求/響應模型相結合,支持多種功能,可以輕松地將數據從客戶端傳遞到服務器端請求處理程序中,再傳遞回客戶端。 無需ASP.NET-所有本機Delphi和“經典” ISAPI應用程序模型。
Delphi 7將生成ISAPI應用程序代碼-當IIS將請求發送到DLL時,您將獲得一個動作編輯器來處理請求,該請求由客戶端發送的URL決定。 您可以保留會話信息,創建全局緩存,並且在ISAPI DLL的上下文中,基本上可以使用VCL的所有非可視方面。
IIS處理線程-可能處理的並發連接遠遠超出您的需要-並且還使您能夠確定一次可以加載DLL的實例的數量,以及許多其他選項,例如回收,各種形式的身份驗證和安全級別。 您可以使用IIS的應用程序池功能進行擴展等。
我已經使用這種體系結構開發了幾種大型企業級解決方案(Delphi exe中嵌入了Indy客戶端)。 一旦掌握了Delphi的ISAPI應用程序模型的基礎知識和IIS部署的缺陷,它就會變得穩定且相對“無痛”。
如果您有此選項,為什么還要重新發明輪子呢?
在此處查看示例: http : //sourceforge.net/p/xxm/code/HEAD/tree/trunk/Delphi/http/
線程池邏輯在這里: http : //sourceforge.net/p/xxm/code/HEAD/tree/trunk/Delphi/common/xxmThreadPool.pas
Xxm實際上提供了您可以針對其進行編碼的接口,因此結果可以通過IIS,Apache或具有多線程的純 HTTP服務器進行移植。 還有一個http.sys版本和一個連接器,可直接在Internet Explorer中本地運行(非常適合調試)。 它們每個都有一個“自動更新”版本,該版本將熱交換項目DLL,並將其用於任何新請求(對於實時服務器而言非常有用)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.