2010-06-10 25 views
2

我开始使用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模块我也必须遵循这些说明:

的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似乎只是今天讨厌我。

+0

不是说我知道什么关于线程模型的isapi模块,但它听起来像是一个线程问题。也许如果你为你的dll选择了不同的线程模型,Apache会更快乐吗? – 2010-06-11 06:40:58

+0

@Marjan:我偶然发现了这个页面:http://www.drbob42.com/examines/examin80.htm,同时搜索关于CoInitFlags和COINIT_MULTITHREADED的信息,试图在apache中查找有关线程的信息。 基于这些信息,我已经能够创建一个生成Apache模块的项目,这很好,因为现在基本上我有一个代码库来定义服务和两个项目文件,一个产生一个ISAPI DLL,另一个产生一个Apache模块。我现在正在测试Apache模块以查看是否可以解决问题。 – 2010-06-11 13:37:03

+0

我也必须使用此页上的信息来创建Apache 2.2模块,而不是Apache 2.0模块:http://leonardorame.blogspot.com/2009/04/apache-22x-modules-with-delphi。 html – 2010-06-11 13:38:58

回答

-1

要排除您是否错误地调用它,请使用带有SoapUI的WSDL并发送一些测试消息。看看他们是否成功。如果它在SoapUI中工作,那么这是客户端代码的问题。如果它不起作用,那么它就是服务器端的东西。另请参阅SoapUI是否以不同于您的期望的方式构建请求对象。

+0

我可以向你保证它被正确调用。我已经使用ISAPI dll设置了IIS,并将其称为测试客户端,没有错误。然后,我可以将Apache配置为在相同的URL上托管该DLL,以便对于测试客户端,它看起来是完全相同的服务器。测试客户端在测试之间不会更改。测试之间不会更改DLL。唯一的区别是如果Apache正在托管或IIS正在托管。 – 2010-06-23 10:38:53