2016-04-12 56 views
3

我尝试使用PHP使用SOAP服务时遇到了一个奇怪的问题。它忽略了我的请求,并不断返回上一个命令的结果! SOAP驻留在一台收银机中,它有一个'错误'的wsdl指向一个公共IP端点,我不得不手动编辑它。 WSDL文件是http://192.168.1.20/MyEcrResponce.wsdl我下载了它,并以“192.168.1.20”替换了所有错误的IP引用,然后我在本地保存它作为MyEcrResponce.wsdl:PHP SOAP不断返回旧结果

<?xml version="1.0" encoding="utf-8"?> 
<wsdl:definitions xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://192.168.1.20/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://192.168.1.20/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> 
    <wsdl:types> 
    <s:schema elementFormDefault="qualified" targetNamespace="http://192.168.1.20/"> 
     <s:element name="Cmd"> 
     <s:complexType> 
      <s:sequence> 
      <s:element minOccurs="1" maxOccurs="1" name="CmdText" type="s:string" /> 
      </s:sequence> 
     </s:complexType> 
     </s:element> 
     <s:element name="CmdResponse"> 
     <s:complexType> 
      <s:sequence> 
      <s:element minOccurs="1" maxOccurs="1" name="CmdReply" type="s:string" /> 
      <s:element minOccurs="1" maxOccurs="1" name="LcdLine1" type="s:string" /> 
      <s:element minOccurs="1" maxOccurs="1" name="LcdLine2" type="s:string" /> 
      </s:sequence> 
     </s:complexType> 
     </s:element> 
     <s:element name="GetAppStatus"> 
     <s:complexType> 
      <s:sequence> 
      <s:element minOccurs="1" maxOccurs="1" name="SerialNo" type="s:string" /> 
      <s:element minOccurs="1" maxOccurs="1" name="RetData"  type="s:string" /> 
      </s:sequence> 
     </s:complexType> 
     </s:element> 
     <s:element name="GetAppStatusResponse"> 
     <s:complexType> 
      <s:sequence> 
      <s:element minOccurs="1" maxOccurs="1" name="GetAppStatusResult" type="s:unsignedByte" /> 
      <s:element minOccurs="1" maxOccurs="1" name="RetData" type="s:string" /> 
      </s:sequence> 
     </s:complexType> 
     </s:element>  
    </s:schema> 
    </wsdl:types> 
    <wsdl:message name="CmdSoapIn"> 
    <wsdl:part name="parameters" element="tns:Cmd" /> 
    </wsdl:message> 
    <wsdl:message name="CmdSoapOut"> 
    <wsdl:part name="parameters" element="tns:CmdResponse" /> 
    </wsdl:message> 
    <wsdl:message name="GetAppStatusSoapIn"> 
    <wsdl:part name="parameters" element="tns:GetAppStatus" /> 
    </wsdl:message> 
    <wsdl:message name="GetAppStatusSoapOut"> 
    <wsdl:part name="parameters" element="tns:GetAppStatusResponse" /> 
    </wsdl:message> 
    <wsdl:portType name="MyEcrResponceSoap"> 
    <wsdl:operation name="Cmd"> 
     <wsdl:input message="tns:CmdSoapIn" /> 
     <wsdl:output message="tns:CmdSoapOut" /> 
    </wsdl:operation> 
    <wsdl:operation name="GetAppStatus"> 
     <wsdl:input message="tns:GetAppStatusSoapIn" /> 
     <wsdl:output message="tns:GetAppStatusSoapOut" /> 
    </wsdl:operation> 
    </wsdl:portType> 
    <wsdl:binding name="MyEcrResponceSoap" type="tns:MyEcrResponceSoap"> 
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" /> 
    <wsdl:operation name="Cmd"> 
     <soap:operation soapAction="http://192.168.1.20/Cmd" style="document" /> 
     <wsdl:input> 
     <soap:body use="literal" /> 
     </wsdl:input> 
     <wsdl:output> 
     <soap:body use="literal" /> 
     </wsdl:output> 
    </wsdl:operation> 
    <wsdl:operation name="GetAppStatus"> 
     <soap:operation soapAction="http://192.168.1.20/GetAppStatus" style="document" /> 
     <wsdl:input> 
     <soap:body use="literal" /> 
     </wsdl:input> 
     <wsdl:output> 
     <soap:body use="literal" /> 
     </wsdl:output> 
    </wsdl:operation>  
    </wsdl:binding> 
    <wsdl:service name="MyEcrResponce"> 
    <wsdl:port name="MyEcrResponceSoap" binding="tns:MyEcrResponceSoap"> 
     <soap:address location="http://192.168.1.20/MyEcrResponce/" /> 
    </wsdl:port> 
    </wsdl:service> 
</wsdl:definitions> 

我已经使用的形式在C#中的客户端,取而代之的溶液中所有引用的公网IP 192.168.1.20,和正常工作:

private void button1_Click(object sender, EventArgs e) 
{ 
    string reply = ""; 
    string LcdMsg1 = ""; 
    string LcdMsg2 = ""; 

    Uri ur = new Uri("http://192.168.1.20/MyEcrResponce.cgx"); 

    DeviceWS.MyEcrResponceSoapClient DevHD = new DeviceWS.MyEcrResponceSoapClient(); 
    DevHD.Endpoint.Address = new System.ServiceModel.EndpointAddress(ur); 

    DevHD.ClientCredentials.UserName.UserName = "user"; 
    DevHD.ClientCredentials.UserName.Password = "pass";  

    reply = DevHD.Cmd(CmdTxt.Text, out LcdMsg1, out LcdMsg2); 

    ReplyTxt.Text = reply; 
    LCD01.Text = LcdMsg1; 
    LCD02.Text = LcdMsg2;  
} 

我的PHP客户端看起来是这样的:

$client = new SoapClient(
dirname(__FILE__) . DIRECTORY_SEPARATOR . 'MyEcrResponce.wsdl', 
array('location' => 'http://192.168.1.20/MyEcrResponce.cgx', 
    'login' => 'user', 
    'password' => 'pass', 
    'trace' => 0, 
    'cache_wsdl' => WSDL_CACHE_NONE)); 

$cmd = new StdClass(); 
$cmd->CmdText = 'a/'; 

var_dump($client->Cmd($cmd)); 

无论WHI ch组合我尝试在PHP中总是得到C#client命令的最后结果。似乎所有使用PHP的请求都被忽略。似乎有一个C#可以跳过的缓存,但PHP不能。在php.ini中,'soap.wsdl_cache_enabled'和'soap.wsdl_cache'都设置为0.我使用SoapUI和其他SOAP测试人员获得相同(错误)的行为。有任何想法吗?

更新1: PHP $ client - > __ getTypes();返回此:

array (4) [ 
    string (31) "struct Cmd { 
string CmdText; 
}" 
    string (76) "struct CmdResponse { 
string CmdReply; 
string LcdLine1; 
string LcdLine2; 
}" 
    string (58) "struct GetAppStatus { 
string SerialNo; 
string RetData; 
}" 
    string (82) "struct GetAppStatusResponse { 
unsignedByte GetAppStatusResult; 
string RetData; 
}" 
] 

更新2:使用this post我启用跟踪日志C#客户机来检查工作的SOAP请求,这是这一个:

{ 
Content-Type: text/xml; charset=utf-8 
SOAPAction: "http://192.168.1.20/Cmd" 
Accept-Encoding: gzip, deflate,gzip, deflate 
Authorization: Basic xxxxxxxxxxxxxxxx 
Host: 192.168.1.20 
Content-Length: 207 
Expect: 100-continue 
} 

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
    <s:Body> 
     <Cmd xmlns="http://192.168.1.20/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
      <CmdText>a/</CmdText> 
     </Cmd> 
    </s:Body> 
</s:Envelope> 

不幸的是,结果还是一样当我将请求复制粘贴到PHP或SoapUI时。

更新3:所以,今天是星期一。收银机和PHP服务器都在星期五关闭,我今天打开它们。我在运行PHP脚本之前清除了PHP服务器中的所有缓存文件,并且收到了我在星期五发送的最后一个成功命令的回复!我点附近相信,我必须非常愚蠢的......

+0

尝试把 的ini_set( 'soap.wsdl_cache_enabled', '0'); ini_set('soap.wsdl_cache_ttl','0'); – WhSol

+0

我已经提到缓存被禁用。 – nasos

回答

0

我设法解决我的问题,至少在某种程度上。我无法使SOAP请求正常工作,但我设法使用websockets成功进行通信。我坚持使用SOAP,因为我有更多的经验,但我不得不放弃。我想要一些非常轻巧的东西(我想避免大型的基于作曲家的库),所以经过大量搜索后,我发现了this post,这是我根据自己的需求量身定制的,现在我收到了宝贵的回复。对于面临相同或类似问题的其他人,收银机正在使用RBS软件(希腊公司)和Keil-EWeb服务器。我的修改工作的PHP代码如下:

class WebsocketClient 
{ 
    private $_Socket = null; 

    public function __construct($host, $port) 
    { 
     $header = "GET/HTTP/1.1\r\n"; 
     $header.= "Host: ".$host.":".$port."\r\n"; 

     $this->_Socket = fsockopen($host, $port, $errno, $errstr, 2); 
     fwrite($this->_Socket, $header) or die('Error: ' . $errno . ':' . $errstr); 
     $response = fread($this->_Socket, 2000); 
    } 

    public function __destruct() 
    { 
     fclose($this->_Socket); 
    } 

    public function sendData($data) 
    { 
     fwrite($this->_Socket, $data) or die('Error:' . $errno . ':' . $errstr); 
     $wsData = fread($this->_Socket, 2000); 
     $retData = trim($wsData,"\x00\xff");   
     return mb_convert_encoding($retData,'utf-8','ISO-8859-7'); // Returns garbage in case of greek (or other letters) 
    } 
} 

$WebSocketClient = new WebsocketClient('192.168.1.20', 9101); 
echo $WebSocketClient->sendData('a/'); 
unset($WebSocketClient); 
0

尝试把

ini_set('soap.wsdl_cache_enabled', '0'); 
ini_set('soap.wsdl_cache_ttl', '0'); 

之前创建客户端。

我现在使用NO_CACHE创建客户端的时候有一些帮助。

+0

我已经提到缓存被禁用。 – nasos