【问题标题】:PHP SoapClient using WCF service hosted in Windows application on Windows 2008 ServerPHP SoapClient 使用托管在 Windows 2008 Server 上的 Windows 应用程序中的 WCF 服务
【发布时间】:2011-12-06 05:22:40
【问题描述】:

此问题涉及使用托管在 Windows 2008 Server 上的 Windows 应用程序中的 WCF 服务的要求,来自同一服务器上托管在 IIS 7 中的 PHP 脚本,以及托管在其他地方的其他应用程序。

该应用程序已在使用 Visual Studio 2010、.NET Framework 4、IIS 7 和各种 PHP 版本的 Windows 7 机器上开发和测试。

在Windows 7机器上,netsh使用如下。

netsh http add urlacl url=http://localhost:8000/WCFService/ user=machinename\user

其他各种端口也成功添加并在测试期间使用。

将应用程序复制到 Windows 2008 Server 后,成功地测试了应用程序的基本部分。

在 Windows 2008 Server 上使用了相同的 netsh 命令,但将 localhost 替换为服务器 IP 和带有域的机器名,如下所示:

netsh http add urlacl url=http://serveripaddress:8000/WCFService/ user=domain\user

在尝试使 PHP SoapClient 工作期间,尝试了各种 user="..." 选项,包括“everyone”。

初始的PHP SoapClient脚本如下:

try {
  $client = new SoapClient("http://serveripaddress:8000/WCFService/?wsdl");
} catch (Exception $e) {
  echo $e->getMessage(), "\n"; 
  exit();
}

在初始测试期间,遇到以下错误:

警告: SoapClient::SoapClient(http://serveripaddress:8000/WCFService/?wsdl) [soapclient.soapclient]:打开流失败:HTTP 请求失败! 在第 7 行的 C:\inetpub\wwwroot\Sites\www.myurl.com\WCF-Test.php 中

警告:SoapClient::SoapClient() [soapclient.soapclient]: I/O 警告:无法加载外部实体 "http://serveripaddress:8000/WCFService/?wsdl" 在 C:\inetpub\wwwroot\Sites\www.myurl.com\WCF-Test.php 在第 7 行

SOAP-ERROR:解析 WSDL:无法从 “http://serveripaddress:8000/WCFService/?wsdl”:加载失败 外部实体“http://serveripaddress:8000/WCFService/?wsdl”

经过一番折腾后,错误减少到以下内容:

SOAP-ERROR:解析 WSDL:无法从 “http://serveripaddress:8000/WCFService/?wsdl”:加载失败 外部实体“http://serveripaddress:8000/WCFService/?wsdl”

然后我将 wsdl 提取到一个文件中并使用以下 PHP 脚本:

try {
  $client = new SoapClient("wsdl\wcf-wsdl.wsdl");
} catch (Exception $e) {
  echo $e->getMessage(), "\n"; 
  exit();
}

然后错误略微更改为以下内容:

SOAP-ERROR: Parsing Schema: can't import schema from 'http://serveripaddress:8000/WCFService/?xsd=xsd0'

我认为当前的问题与服务的“可见性”、客户端以及可能的权限有关。

看了几十篇帖子,还是没找到解决这个问题的办法。

我们将不胜感激。

非常感谢。

【问题讨论】:

    标签: php wcf


    【解决方案1】:

    如果 WCF 服务是您托管的东西,以便 php 客户端访问它,您需要有一个平面 wsdl。关于如何生成 Flat Wsdl,请点击以下链接:

    How to flatten your wsdl

    作为 .NET 4.5 的一部分,框架中将提供相同的功能。希望对您有所帮助。

    【讨论】:

    • 您好 Rajesh,感谢您的回答。我当然会仔细查看您提供的链接中的帖子。
    • 我的意思是补充一点,我的解决方案在 Windows 7 下的开发系统中完美运行,使用基本相同的 wsdl。我不确定这是否会对平面 wsdl 产生影响。
    • 为了使您的服务具有互操作性,最好的办法是拥有平面 wsdl。在您的开发环境中,您可能有权访问服务器以在上述位置下载 xsd 吗? xsd=xsd1 等,但想象一下外部客户端试图访问您服务器上的资源.. .svc?xsd=xsd1。您服务器上的防火墙可能不允许访问该资源。
    • Rajesh,这无疑帮助我克服了 SoapClient 创建错误,非常感谢。它似乎证实了这些问题与 wsdl 和 wcf 配置有关,而不是访问问题,因此这条隧道的尽头是光明的。
    • 目前我在方法调用过程中遇到错误。此服务最初是使用添加新服务库时生成的默认接口构建的,因此调用 GetData。指示配置问题的错误之一如下。捕获的异常:反序列化操作“GetData”的请求消息正文时出错。 OperationFormatter 遇到无效的消息正文。预计会找到名称为“GetData”和命名空间“”的节点类型“元素”。找到名称为“参数”和命名空间“”的节点类型“元素”
    【解决方案2】:

    如果您知道您正在使用 .NET WCF 服务,您只需将下载 wsdl 的位置从 .svc?wsdl 更改为 .svc?singleWsdl,WCF 服务器将为您处理递归/链接工作.

    【讨论】:

      【解决方案3】:

      这可能是答案,.net 的默认配置会导致此错误。 https://bugs.php.net/bug.php?id=47761

      【讨论】:

      • 始终欢迎提供指向潜在解决方案的链接,但请在链接周围添加上下文,以便您的其他用户了解它是什么以及它存在的原因。始终引用重要链接中最相关的部分,以防目标站点无法访问或永久离线。
      猜你喜欢
      • 2016-04-11
      • 2011-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多