我开始使用Delphi 2009创建的ISAPI DLL,该模块在Windows XP上的IIS 5.1中运行时按预期执行。当使用Apache 2.2.15和mod_isapi托管时,这个模块无法正常运行。为了消除mod_isapi存在缺陷的可能性,已经创建了相同服务的Apache共享对象模块。然而,Apache模块也会出现类似的问题。Apache托管的Web服务不处理TRemotable类
通过创建两个共享实现代码的项目,我已经能够创建具有相同实现的ISAPI DLL和Apache模块。所以他们之间的唯一区别是他们如何连接到他们的主机Web服务。这给了我三个选项主持此服务:
- IIS + ISAPI DLL
- 的Apache + Apache模块
- 的Apache + mod_isapi + ISAPI DLL。
这两个项目都实现了一个简单的Web SOAP服务进行测试。当您使用Delphi IDE创建新的Soap Server应用程序时,所有序列化,反序列化,封送处理等都由自动生成的代码处理。界面有几个简单的测试功能。
为了创建一个Apache模块我也必须遵循这些说明:
- http://www.drbob42.com/examines/examin80.htm
- http://www.drbob42.com/Delphi7/Apache2040.htm
- http://leonardorame.blogspot.com/2009/04/apache-22x-modules-with-delphi.html
的SOAP服务实现的接口是相当简单的。它有一些变化来测试不同的事情。
IPdiSvc2 = interface(IInvokable)
['{532DCDD7-D66B-4D2C-924E-2F389D3E0A74}']
function Echo(data:string): string; stdcall;
function SendFile1(request: TSendFileRequest; attachment: TSOAPAttachment):
TSendFileResponse; stdcall;
function SendFile2(request:string): TSendFileResponse; stdcall;
function SendFile3():TSendFileResponse; stdcall;
function SendFile4(attachment: TSoapAttachment): TSendFileResponse; stdcall;
function SendFile5(request: TSendFileRequest):TSendFileResponse; stdcall;
end;
TSendFileRequest和TSendFileResponse也很简单。
TSendFileRequest = class(TRemotable)
private
FFilename: string;
published
Property Filename: string read FFilename write FFilename;
end;
TSendFileResponse = class(TRemotable)
private
FFileID: Int64;
published
Property FileID: Int64 read FFileId write FFileID;
end;
该接口的实现充满了虚拟代码,只是创建一个结果对象发送回客户端。实施中不存在重要的代码。
当通过ISAPI在IIS中托管时,服务公开的所有方法都可以正常工作。
在Apache中托管时,包含TRemotable参数的任何方法都有错误。在这个接口中,SendFile1和SendFile5受到影响,因为它们有一个TSendFileRequest作为参数。第一次调用SendFile1或SendFile5按预期工作。成功调用SendFile1或SendFile5后,下一次调用任何方法会导致访问冲突。在Apache共享对象模块和使用mod_isapi的ISAPI DLL中都会观察到此行为。
我不确定问题在哪里,但我看到三个选项:我的代码,Delphi代码或Apache代码。我无法弄清楚在哪里。
这个问题一直很令人沮丧,因为完全相同的二进制ISAPI DLL在IIS中工作,但在Apache中不起作用。我会把它记在ISAPI主机的实现差异上,但是在Apache共享对象模块中出现同样的错误意味着其他事情正在发生。
为了完整性,我决定创建一个CGI版本的相同的web服务。在IIS下运行时,CGI版本完美运行。在Apache中运行时,所有请求都会导致错误:“XML文档必须具有顶级元素。行:0”
看来Apache似乎只是今天讨厌我。
不是说我知道什么关于线程模型的isapi模块,但它听起来像是一个线程问题。也许如果你为你的dll选择了不同的线程模型,Apache会更快乐吗? – 2010-06-11 06:40:58
@Marjan:我偶然发现了这个页面:http://www.drbob42.com/examines/examin80.htm,同时搜索关于CoInitFlags和COINIT_MULTITHREADED的信息,试图在apache中查找有关线程的信息。 基于这些信息,我已经能够创建一个生成Apache模块的项目,这很好,因为现在基本上我有一个代码库来定义服务和两个项目文件,一个产生一个ISAPI DLL,另一个产生一个Apache模块。我现在正在测试Apache模块以查看是否可以解决问题。 – 2010-06-11 13:37:03
我也必须使用此页上的信息来创建Apache 2.2模块,而不是Apache 2.0模块:http://leonardorame.blogspot.com/2009/04/apache-22x-modules-with-delphi。 html – 2010-06-11 13:38:58