首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Delphi 7 Indy 9多线程HTTP服务器

Delphi 7 Indy 9多线程HTTP服务器
EN

Stack Overflow用户
提问于 2014-06-29 13:28:47
回答 4查看 3K关注 0票数 2

我需要编写一个多线程HTTP服务器。我知道印第通过IdThreadMgrPool处理线程。

我的要求很简单:有一个服务器可以接受多个同时的客户端(web浏览器发布请求),运行有限数量的线程来调用Delphi (很可能独立于连接线程),并返回结果。

非阻塞将是终极的(如node.js)。

关于这个话题有几篇这样的帖子。我在这里(或通过谷歌)找不到的是如何使用IdThreadMgrPool的一个例子。我看到一些帖子说必须使用它,但没有举例说明如何使用。印第的网站上也没有任何例子。

有人能给我举个例子吗?或者,是否有一个FOS框架可以解决这一问题?

一种方法是让Indy正常地生成多个线程,然后让这些线程访问运行DLL的受控线程池。如果这是合理的,那么我只需要知道“正常”的案例用法例子。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-06-30 03:46:00

如果您有一个可用的Windows服务器,我建议使用Delphi 7编写一个ISAPI DLL,并将其部署到IIS上,这将处理所有服务器端问题,特别是如果您有IIS7.5(或更好的)服务器2008 R2。您的客户端可以使用Indy连接到IIS,Indy客户端与Delphi ISAPI的请求/响应模型相结合,支持几种特性,这些特性使数据从客户端传递到服务器端请求处理程序并返回到客户端非常容易。不需要ASP.NET -所有本地和“经典”ISAPI应用程序模型。

Delphi 7将生成ISAPI应用程序代码--当IIS将请求发送到DLL时,您将得到一个操作编辑器来处理请求,DLL由客户端发送的URL确定。您能够持久化会话信息,创建全局缓存,并且基本上拥有ISAPI DLL上下文中VCL的所有非可视方面。

IIS处理线程--可能会处理比您需要的更多的同时连接--还使您能够确定可以一次加载多少DLL实例,以及许多其他选项,例如回收、各种形式的身份验证和安全级别。您可以使用IIS的应用程序池功能进行缩放等。

我使用这个架构开发了几个大型企业级解决方案(Indy客户端嵌入了Delphi exe中)。一旦您了解了Delphi的ISAPI应用程序模型和IIS部署的错误,它是稳定和相对“无痛”的。

如果你有这个选择,为什么要重新发明方向盘?

票数 2
EN

Stack Overflow用户

发布于 2014-06-29 15:33:16

要使用TIdThreadMgrPool,所要做的至少是创建一个实例,将其分配给TIdHTTPServer.ThreadMgr属性,并设置其PoolSize属性。所有这些都可以在设计时完成。

请记住,PoolSize并不限制服务器上的连接数量。为此,服务器拥有自己的MaxConnections属性。例如,您可以拥有一个10的PoolSize,并同时连接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发送信号。然后,等待的客户端线程将被解除阻塞,并可以根据需要将记录的响应数据发送到客户端。

票数 4
EN

Stack Overflow用户

发布于 2014-06-29 22:07:08

Indy服务器不能很好地扩展。

考虑使用http.sys内核模式服务器,基于iocp。

我们的开源SynCrtSock单元提供了一个高性能的http服务器,从Delphi5到XE6都能很好地工作。

例如,参见此示例代码

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24476493

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档