2

I'm new to PHP. After lots of search I managed to somehow use my web service that is created by Java with PHP but the problem is the constructor of SoapClient class is very slow. Here's my PHP code:

<?
require_once('SOAP/Client.php'); 
$url = "http://127.0.0.1:8024/_RS?wsdl";
$sc = new SoapClient($url);
?>

This takes up to 3 minutes some times. I don't know what the problem is. After creating the constructor I could use it in a for loop for 50 times in 1 second so I'm pretty sure that the constructor is the part that is slowing down my code.

What do you think is causing the problem?

Thank you in advance.

PS: More information in my other question: https://stackoverflow.com/questions/5929669/call-a-wsdl-web-service-created-by-java-from-nushphere-phped

PPS: As suggested by AJ, I used XDebug and kcachegrind to analyze the problem. As you can see, I was right. Here's the picture: XDebug result in kcachegrind both in % (up) and time(down).

Community
  • 1
  • 1
Alireza Noori
  • 14,961
  • 30
  • 95
  • 179

3 Answers3

4

I have the same problem. The php SoapClient is very fast with the same webservice deployed on Tomcat. I tried doing a "wget" to see if the headers in the response was different and as the problem is with the WSDL caching the difference I found might be the reason:

With Tomcat:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Content-Length: 23925
Date: Thu, 08 Mar 2012 23:13:10 GMT
Connection: keep-alive

With Endpoint.publish(...)

HTTP/1.1 200 OK
Content-type: text/xml;charset=utf-8
Content-length: 23837

Now I just need to find out how to force the Endpoint.publish(...) to insert a Server, Date, or Connection-header.

(Edit) I found a solution: The issue is not only with Chunked data but with "Keep-Alive". This can be prevented by setting the header "Connection: Close" in a stream_context. Please see below:

class ImprovedSoapClient extends SoapClient
{
    public function __construct($wsdlLocation)
    {
        parent::__construct(
            $wsdlLocation 
            , array(
                , 'cache_wsdl' => WSDL_CACHE_NONE
                , 'stream_context'=>stream_context_create(
                    array('http'=>
                        array(
                            'protocol_version'=>'1.0'
                            , 'header' => 'Connection: Close'
                        )
                    )
                )
            )
        );
    }
}
Emanuel Greisen
  • 154
  • 1
  • 3
  • Thanks. Please let me know if you found out the solution. – Alireza Noori Mar 09 '12 at 07:55
  • I managed to add the headers - but in vain. Php's SoapClient still wants to spend 60 seconds cashing the WSDL, and 60 seconds caching the XSD. – Emanuel Greisen Mar 09 '12 at 08:25
  • Haha, setting the "default_socket_timeout" to 5 reduced the caching to 10 seconds - seems that the difference might be the handling of the connection (who terminates it) which is different from Tomcat and Endpoint.publish(....). – Emanuel Greisen Mar 09 '12 at 08:26
  • 1
    I have found out exactly what the problem is. I am running PHP version 5.2, in this version the HTTP-wrappers (used by the SoapClient) do not support "Chunked" data. Due to this, the connection stays open and is closed when it times out ("default_socket_timeout"). – Emanuel Greisen Mar 18 '12 at 17:24
  • I have been unable to make the "Endpoint.publish(...)" produce a "Content-length" when I access is via PHP (both SoapClient-constructor, and file_get_contents(...)). Obviously fetching the WSDL with curl works like a charm. – Emanuel Greisen Mar 18 '12 at 17:25
1

I would guess that it's not the constructor of the PHP class, but instead it's probably making the first call to your Java Web service - before any objects have been initialized on the Java application.

But, you should determine this for sure by using a PHP profiling tool, like Xdebug:

http://www.xdebug.org/docs/profiler

AJ.
  • 27,586
  • 18
  • 84
  • 94
  • The service is just a tiny hello world service just for testing purpose. You can see the code in the link at the end of the question. I don't think that the java part is slowing things down becuase a silverlight consumer works just fine with the same service. Don't you agree? – Alireza Noori May 10 '11 at 01:07
  • That could be true...again, the only way to know for **sure** what is causing your slowdown is to use a profiling tool. It will show you the exact line that is taking the longest. – AJ. May 10 '11 at 01:09
  • Thank you. Couldn't I just echo some text before and after the constructor to see the difference? I'm new to PHP and I'll take me some time to be able to use the tool you provided. – Alireza Noori May 10 '11 at 01:16
  • That will only tell you the time offset before and after the constructor call. A profiler will provide you with a full listing of the entire stack of calls inside of your constructor (all of the functions it calls, and the functions those functions call, etc.) and for each one, it will show how long it takes. – AJ. May 10 '11 at 01:30
  • OK. So I will look more into it. Thanks again. – Alireza Noori May 10 '11 at 01:34
  • No problem, please report back your findings here when you complete your research so that others may benefit from it. – AJ. May 10 '11 at 01:36
  • I posted the result in an edit. The constructor takes about 95% of the execution time and its about 2 minutes! – Alireza Noori May 10 '11 at 12:13
  • Just calling the constructor itself wouldn't take this long...the constructor is calling other functions inside of it. You still need to "step into" the SOAPClient() call to see what function its calling is actually causing the latency. – AJ. May 10 '11 at 13:07
  • The __"step into"__ in the debug session doesn't work on the constructor (it doesn't show more code). How can I investigate it more? I wonder, if you create same service and client (code is available in the linked question) does it take this long in your system or it's just in mine? – Alireza Noori May 10 '11 at 18:00
  • Sorry to reply to an old issue, but did you ever find a solution for this problem? I am experiencing the same thing and can't figure out what it is. – Naatan Sep 21 '11 at 20:38
  • @Naatan, no I couldn't find a solution, I switched to Thrift. You can find a good tutorial by myself at [my blog](http://www.alireza-noori.com/programming/thriftpart-one-introduction/) – Alireza Noori Oct 23 '12 at 08:21
1

This looks pretty similar to your problem: http://www.ozonesolutions.com/programming/2011/05/nsclient-login-time/ Its using php toolkit instead of java, but the solution may still apply.

Daniel
  • 794
  • 10
  • 20
  • Thanks. I don't want to look more into it as I found Thrift a more reasonable solution. Anyway I mark this one as an answer 'cause it seems like a good start. – Alireza Noori Sep 26 '11 at 20:47