ISAPI 概 念
ISAPI 即Internet Server Application Program Interface, 是 微 软 提 供 的 一 套 面 向Internet 服 务 的API 接 口, 它 能 实 现CGI 能 提 供 的 全 部 功 能, 并 在 此 基 础 上 进 行 了 扩 展, 如 提 供 了 过 滤 器 应 用 程 序 接 口。
4.2 ISAPI 程 序 语 言
由 于 开 发ISAPI 应 用 要 用 到 微 软 的 一 套API, 所 以 能 用 来 开 发ISAPI 应 用 的 语 言 不 如CGI 那 么 多。 主 要 有Visual C++ 4.1 以 上 版 本,Visual Basic 5.0、Borland C++ 5.0 也 可 以。
4.3 ISAPI 原 理
ISAPI 的 工 作 原 理 和CGI 大 体 上 是 相 同 的, 都 是 通 过 交 互 式 主 页 取 得 用 户 输 入 信 息, 然 后 交 服 务 器 后 台 处 理。 但 是 二 者 在 实 现 机 制 上 大 相 庭 径。ISAPI 与CGI 最 大 的 区 别 在 于: 不 同 于CGI, 在ISAPI 下 建 立 的 应 用 程 序 是 以 动 态 连 接 库 的 形 式 存 在; 而CGI 的 应 用 程 序 一 般 都 是 可 执 行 程 序。
4.4 ISAPI 程 序 的 执 行
ISAPI 应 用 的 工 作 流 程 与CGI 有 一 些 不 同。ISAPI 应 用 的DLL 不 仅 可 以 象CGI 程 序 一 样 被 用 户 请 求 激 活, 还 可 以 被 系 统 预 先 激 活 来 监 视 用 户 输 入; 对 于 被 用 户 激 活 的DLL, 在 处 理 完 一 个 用 户 请 求 后 不 会 马 上 消 失, 而 是 继 续 驻 留 在 内 存 中 等 待 处 理 别 的 用 户 输 入, 直 到 过 了 一 段 时 间 后 一 直 没 有 用 户 输 入。
4.5 ISAPI 性 能 评 价
一 个ISAPI 的DLL, 可 以 在 被 用 户 请 求 激 活 后 长 驻 内 存, 等 待 用 户 的 另 一 个 请 求, 还 可 以 在 一 个DLL 里 设 置 多 个 用 户 请 求 处 理 函 数, 此 外,ISAPI 的DLL 应 用 程 序 和WWW 服 务 器 处 于 同 一 个 进 程 中, 效 率 要 显 著 高 于CGI。
不 过ISAPI 的 平 台 兼 容 性 较 差, 目 前 只 能 用 于 微 软 自 己 的Windows 95 和NT 操 作 系 统 上, 服 务 器 平 台 也 仅 限 于IIS(Internet Information Server) 和MS personal web server 以 及NT workstation 上 的peer web server。
五、ISAPI 的 实 现
能 够 支 持ISAPI 开 发 的 平 台 只 有 微 软 的 几 个 平 台 组 合( 如NT+IIS,WIN95+MS personal web server)。 因 此 开 发ISAPI 只 能 这 几 个 平 台 上。 开 发 语 言 前 已 有 述, 这 里 向 大 家 推 荐Visual C++ 4.2 版, 它 的Wizard 提 供 了 专 门 制 作ISAPI 的 功 能 项。
下 面 是 个 简 单 的 例 子, 功 能 是 将 用 户 从 浏 览 器 上 的 输 入 简 单 地 回 显 给 用 户, 功 能 简 单, 但 是 具 备 一 个 典 型 的ISAPI 全 部 流 程。 源 程 序 如 下( 大 部 分 为Wizard 生 成 的 代 码):
1. 主 程 序:
// ISAPI1.CPP - Implementation file for your Internet Server
#include "stdafx.h"
#include "isapi1.h"
///
// The one and only CWinApp object
// NOTE: You may remove this object if you alter your project to no
// longer use MFC in a DLL.
CWinApp theApp;
///
// command-parsing map
BEGIN_PARSE_MAP(CIsapi1Extension, CHttpServer)
/************* My codes begin here ***********/
ON_PARSE_COMMAND(RegisterUser,
CIsapi1Extension, ITS_PSTR ITS_PSTR ITS_PSTR)
ON_PARSE_COMMAND_PARAMS("First Middle Last")
/************* My codes end here ***********/
END_PARSE_MAP(CIsapi1Extension)
///
// The one and only CIsapi1Extension object
CIsapi1Extension theExtension;
///
// CIsapi1Extension implementation
CIsapi1Extension::CIsapi1Extension()
{
}
CIsapi1Extension::~CIsapi1Extension()
{
}
BOOL CIsapi1Extension::GetExtensionVersion
(HSE_VERSION_INFO* pVer)
{
// Call default implementation for initialization
CHttpServer::GetExtensionVersion(pVer);
// Load description string
TCHAR sz[HSE_MAX_EXT_DLL_NAME_LEN+1];
ISAPIVERIFY(::LoadString(AfxGetResourceHandle(),
IDS_SERVER, sz, HSE_MAX_EXT_DLL_NAME_LEN));
_tcscpy(pVer->lpszExtensionDesc, sz);
return TRUE;
}
///
// CIsapi1Extension command handlers
/****** My code begins here**********/
void CIsapi1Extension::RegisterUser
( CHttpServerContext* pctxt, LPCTSTR
pstrFirst, LPCTSTR pstrMiddle, LPCTSTR pstrLast )
{
// do processing here!
*pctxt << _T("Your name is:");
*pctxt << _T(pstrFirst);
*pctxt << _T("/n");
*pctxt << _T("Your Address is:");
*pctxt << _T(pstrMiddle);
*pctxt << _T("/n");
*pctxt << _T("Your E_mail is:");
*pctxt << _T(pstrLast);
}
/********* My codes end here **********/
// Do not edit the following lines,
which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CIsapi1Extension, CHttpServer)
//{{AFX_MSG_MAP(CIsapi1Extension)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif// 0
2. 主 头 文 件
// ISAPI1.H - Header file for your Internet Server
//isapi1 Extension
#include "resource.h"
class CIsapi1Extension : public CHttpServer
{
public:
CIsapi1Extension();
~CIsapi1Extension();
// Overrides
// ClassWizard generated virtual function overrides
// NOTE - the ClassWizard will add and remove member functions here.
//DO NOT EDIT what you see in these blocks of generated code !
//{{AFX_VIRTUAL(CIsapi1Extension)
public:
virtual BOOL GetExtensionVersion(HSE_VERSION_INFO* pVer);
//}}AFX_VIRTUAL
// TODO: Add handlers for your commands here.
/*********** My coded begin here ( 函 数 声 明) *********/
void RegisterUser( CHttpServerContext* pctxt,
LPCTSTR pstrFirst, LPCTSTR
pstrMiddle, LPCTSTR pstrLast );
/*********My codes end here
DECLARE_PARSE_MAP()
//{{AFX_MSG(CIsapi1Extension)
//}}AFX_MSG
};
3. 动 态 连 接 库 定 义 文 件
/*************************************/
/*ISAPI1.def */
/*************************************/
; ISAPI1.def : declares the module parameters for the DLL.
LIBRARY"ISAPI1"
EXPORTS
HttpExtensionProc
GetExtensionVersion
在 上 述 程 序 中, 定 义 了 一 个CHttpServer 的 类CIsapi1Extension, 这 是 该 程 序 的 主 要 一 个 类, 通 过 它 实 现 与 用 户 交 互 的 功 能。 由ON_PARSE_COMMAND 段 实 现 函 数 映 射, 上 述 程 序 中 定 义 了 该DLL 中 的 一 个 成 员 函 数RegisterUser, 其 功 能 就 是 将 用 户 在 编 辑 框 中 输 入 的 信 息 发 送 回 用 户。 关 于 具 体 实 现 细 节, 可 以 参 看VC4.2 帮 助 文 档。
将 上 述 文 件 编 译 成DLL 后 放 入 服 务 器 主 机 内WWW 服 务 器 指 定 的 用 户 有 执 行 权 限 的Scripts 目 录 里, 该 目 录 的 逻 辑 名 应 和 交 互 主 页 里 的 一 致。 设 置 完 后, 通 过 浏 览 器 连 到 服 务 器 上, 浏 览 该 主 页, 并 输 入 信 息 到 编 辑 框 中。