Apache托管Web服务不处理TRemotable类

时间:2010-06-10 17:47:16

标签: web-services delphi apache isapi

我从使用Delphi 2009创建的ISAPI DLL开始,该模块在Windows XP上的IIS 5.1中运行时按预期执行。使用Apache 2.2.15和mod_isapi托管时,此相同模块无法正常运行。为了消除mod_isapi存在某些缺陷的可能性,已经创建了相同服务的Apache共享对象模块。但是,类似的问题也会出现在Apache模块中。

通过创建两个共享实现代码的项目,我已经能够创建具有相同实现的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共享对象模块中出现同样的错误意味着其他事情正在发生。

为了完整性,我决定创建同一个Web服务的CGI版本。在IIS下运行时,CGI版本运行良好。在Apache中运行时,所有请求都会导致错误:“XML文档必须具有顶级元素.Line:0”

看起来Apache今天只是讨厌我。

1 个答案:

答案 0 :(得分:-1)

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