2

我正在使用 Delphi 编写一个 ISAPI 应用程序。那里有很多教程,但没有人超越经典的 OnAction/Response.Content 示例
问题不言自明。每个请求都会创建一个新的 TWebModule 实例吗?创建后,该 TWebModule 会继续处理该连接的请求吗?
甚至 Delphi 文档也很模糊。我正在尝试找到一种方法来管理应用程序内部的会话,但是教程和文档中的许多细节都不清楚,例如:在请求服务后是否卸载了 DLL?DLL 的“程序”部分(主要的 begin/end.pair)是 DLL 全局初始化吗?是否为每个浏览器创建了 TWebModule(例如,用户试图从同一台计算机上的两个不同浏览器进行连接)?
该应用程序将由在 Windows 2012 R2 上运行的 Apache 2.4 提供服务

4

2 回答 2

1

Delphi TWebModule 封装了几种不同技术中的任何一种,包括 CGI 或 ISAPI。您似乎对 ISAPI 感兴趣。

根据 Microsoft 文档:

https://docs.microsoft.com/en-us/previous-versions/iis/6.0-sdk/ms525172(v=vs.90)

当 IIS 收到映射到 ISAPI 扩展的请求时,会发生以下事件:

  1. 如果 DLL 不在内存中,IIS 会加载它。加载 DLL 时,Windows 会自动调用可选的 DLL 进入/退出函数(通常是 DllMain)。IIS 然后调用扩展的 GetExtensionVersion 入口点函数。

  2. IIS 对传入请求执行较小的预处理。

  3. IIS 创建并填充 EXTENSION_CONTROL_BLOCK 结构以将请求数据和回调函数指针传递给扩展。

  4. IIS 调用 ISAPI 扩展的 HttpExtensionProc 函数,传递一个指向为此请求创建的 EXTENSION_CONTROL_BLOCK 结构的指针。

  5. ISAPI 扩展执行其设计执行的操作:例如,从客户端读取更多数据(如在 POST 操作中),或将标头和数据写回客户端。

  6. 该扩展通过退出 HttpExtensionProc 函数通知 IIS 它已完成对请求的处理。对于同步操作,函数返回 HSE_STATUS_SUCCESS 返回码;对于异步操作,返回码是 HSE_STATUS_PENDING。有关异步操作的更多信息,请参阅异步 I/O 处理。

  7. IIS 对用于请求的连接执行清理,之后如果未启用 Keep-Alive 功能,它会关闭连接。

  8. 一旦不再需要 ISAPI 扩展,IIS 就会调用 TerminateExtension 函数(如果扩展提供了一个)。如果 IIS 配置为缓存 ISAPI 扩展,则在 IIS Web 服务器关闭或重新启动之前不会调用 TerminateExtension。

所以是的,.dll 被加载一次(每个服务器),但连接被单独处理(每个客户端请求)。

于 2021-01-20T18:29:27.100 回答
0

简短回答:并不总是,这取决于
中等回答:这取决于浏览器、Web 服务器和 Delphi
长回答:

  1. 它取决于浏览器上的线程(或进程)。假设一个页面在您的TWebModule上调用三个操作,例如三个href,一个用于加载图像,另一个用于css ,另一个用于 Javascript。浏览器可能会也可能不会同时发送请求。很可能会。
  2. 这取决于服务器。如果它同时接收请求(以几个可丢弃的毫秒分隔),它可能会向您的TWebModule创建多个并发请求,或者可能将它们序列化,如 paulsm4 所述
  3. 这取决于德尔福。跟踪源代码似乎为每个请求创建了一个新的线程/ TWebModule对。但是,该模块被保留以供进一步重用。看来他的行为可以在运行时修改

结论TWebModules对于持久性管理是不可靠的。创建另一种数据模块对我有用,但是:

 MyDataModule :=  TMyDataModule.Create(Application);   
// don´t use Application.CreateForm(MyDataModule)  

MyDataModule中,可以处理持久性。Delphi 不会创建、丢弃或修改它。
PD 从理论上讲,任何 ISAPI DLL 都可以随时被服务器卸载。Apache 有一个保留它的指令:ISAPICacheFile。然而,卸载 DLL 似乎破坏了 ISAPI 改善 CGI 开销的目的。

于 2021-02-15T17:37:13.197 回答