ISAPI 模块中的异步 IO






4.95/5 (10投票s)
2000年5月4日

80679

1122
如何使用异步 IO 从 ISAPI 模块发送数据
引言
ISAPI 模块中的异步 IO 通常被视为一种神秘的技术。但实际上它相当直接,并且能够为您的应用程序带来最高级别的性能和可伸缩性。
一个演示异步 IO 的项目
在浏览 Code Project 网站时,我偶然发现了 Jorge Lodos Vigil 的一个 示例 ISAPI 项目,该项目演示了发送回一个 HTML 页面和一个图像。Jorges 的 ISAPI 返回两种不同类型的数据。页面包含在一个内存缓冲区中,而图像包含在磁盘文件上。向客户端发送数据缓冲区和向客户端发送文件恰好涵盖了使用 ISAPI API 异步发送数据的两种可能方式 - WriteClient
和 TransmitFile
。
ImageServer 项目
ImageServer
ISAPI 扩展本质上是从某个隐藏目录代理图像请求。ImageServer
通过返回一个包含 IMG
元素的 HTML 页面来满足这些请求,该 IMG
元素的源是 ImageServer
扩展。源 URL 经过特殊格式化,以便 ImageServer
知道它应该发送实际的图像而不是包含的页面。
执行异步 IO 的两种方式
在 ISAPI 模块的上下文中,有两种方法可以异步接收或发送数据。您可以使用 ReadClient
或 WriteClient
异步读/写到客户端的任意数据缓冲区,或者使用 TransmitFile
异步将文件发送到客户端。TransmitFile
是一个 Win32 函数,通过使用 ISAPI 函数 ServerSupportFunction
并指定 HSE_REQ_TRANSMIT_FILE
选项来访问。
MSDN 在线库提供了关于 异步 IO 的良好概述,但总的来说,您需要执行以下步骤:
- 设置一个回调,以便在发生 IO 完成事件时收到通知。
- 启动异步 IO。
- 从
HttpExtensionProc
返回HSE_STATUS_PENDING
。 - 当 IO 完成时,清理任何上下文信息,并通知 IIS 您已完成此会话。
关于异步 IO,真正需要记住的只有一件事。那就是,*无论*发送给客户端的数据都必须在收到完成通知之前保持有效。这意味着,它几乎总是会放在堆上。
最后一个要求通常在设计方面会引起最大的麻烦。ISAPI 扩展对性能和可靠性的极端要求排除了频繁访问堆的设计。限制对堆的访问通常通过实现可重用缓冲区对象的池来实现。
ImageServer
的要求没有那么严格。当 ImageServer
需要一个缓冲区或传输上下文时,它只需在堆上创建它。同样,当它完成一个缓冲区的使用时,它只是销毁它。尽管创建受保护的缓冲区池并不难,但它会分散 ImageServer
的核心目的——演示基本的异步 IO。
代码导览
代码很简单,并且有大量的注释,因此应该很容易理解。以下是您会发现的主要内容:
- 有一个主要的类
CImageServer
,它封装了此应用程序所需的所有功能。此类在 Server.h 中声明,在 Server.cpp 中实现。 CImageServer
的一个静态实例位于 ImageServer.cpp 中。该文件还包含 ISAPI DLL 的主要入口点 -DllMain
、GetExtensionVersion
、TerminateExtension
和HttpExtensionProc
。它们都是基本的样板代码,除了HttpExtensionProc
将其行为委托给CImageServer::ServiceRequest
。- 还有两个类作为异步 IO 调用的传输上下文。第一个是
CFilePacket
,它是TransmitFile
的上下文。第二个是tWriteClientPacket
,它实际上是一个结构而不是一个类。它作为您猜到的WriteClient
的上下文。CFilePacket
和tWriteClientPacket
都被声明为CImageServer
声明中的嵌套类/结构。这并没有真正的必要,但它使代码更整洁,因为这些类仅在CImageServer
的函数内部使用。
理解 CImageServer
的工作原理的最佳方法是阅读源代码。一切都始于 CImageServer::ServiceRequest
,注释将引导您继续。
安装
与任何 ISAPI 模块一样,您必须将 DLL 放置在您的 Web 服务器有权访问的某个路径中,并具有执行权限。您还需要一个包含图像的目录,该目录与您在 CImageServer::GetImageDirectory
中硬编码的名称匹配。
关于作者
我工作的公司 Financial Insight Systems Inc. 专注于使用 Microsoft Back Office 产品创建高性能的 Internet 应用程序。我拥有 MCSD 认证,并获得了 Visual C++ 和 SQL Server 的认证,在过去的五年里,我大部分时间都花在开发 ISAPI 模块和基于 Winsock 的客户端/服务器解决方案上。欢迎提出建议和意见。
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。