[英]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.