3

I have a strange problem trying to consume a SOAP service with PHP. It ignores my request, and keeps returning last command's result! The SOAP resides in a cash register machine, which has a 'faulty' wsdl pointing to a public IP endpoint and I had to edit it manually. The WSDL file is in http://192.168.1.20/MyEcrResponce.wsdl which I downloaded it, and replaced all wrong IP references with '192.168.1.20' and then I saved it locally as MyEcrResponce.wsdl:

<?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>

I have made a client in C# using forms, replaced all references in solution from public IP to 192.168.1.20, and works fine:

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;    
}

My PHP client looks like this:

$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));

No matter which combination I try, in PHP I always get the last result of C# client command. It seems that all requests with PHP are ignored. It seems like there is a cache somewhere which C# can overpass, but PHP can't. In php.ini both 'soap.wsdl_cache_enabled' and 'soap.wsdl_cache' are set to 0. I get the same (faulty) behavior with SoapUI and with other SOAP testers. Any ideas?

Update 1: PHP $client->__getTypes(); returns this:

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;
}"
]

Update 2: Using this post I enabled trace log in C# client to check the working SOAP request which is this one:

{
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>

Unfortunately, the result is still the same when I copy-paste the request to PHP or SoapUI.

Update 3: So, today is Monday. Both cash register machine and PHP server were shutdown on Friday and I opened them today. I cleared all cache files from PHP server BEFORE I run the PHP script, and I got the reply from the last successful command I sent on Friday!!! I'm near the point to believe that I have to be very stupid...

Community
  • 1
  • 1
nasos
  • 51
  • 1
  • 6

2 Answers2

0

Try put

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

before create client.

I now you use NO_CACHE when create client by some time it help.

WhSol
  • 116
  • 3
0

I managed to solve my problem, in a way at least. I was unable to make SOAP requests work properly, but I managed to communicate successfully using websockets. I insisted on SOAP because I have much more experience, but I had to give up. I wanted something very light (I wanted to avoid big composer-based libraries), so after a lot of search I found this post, which I tailored to my needs and now I get my precious replies. For anyone else facing the same, or similar, problems, the cash register machine is using RBS software (Greek company) and Keil-EWeb server. My modified working PHP code is following:

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);
nasos
  • 51
  • 1
  • 6