PHP non blocking soap request - php

After a user signs up on my website i need to send a soap request in a method that is not blocking to the user. If the soap server is running slow I don't want the end user to have to wait on it. Is there a way I can send the request and let my main PHP application continue to run without waiting from a response from the soap server? If not, is there a way to set a max timeout on the soap request, and handle functionality if the request is greater than a max timeout?
Edit:
I would ideally like to handle this with a max timeout for the request. I have the following:
//ini_set('default_socket_timeout', 1);
$streamOptions = array(
'http'=>array(
'timeout'=>0.01
)
);
$streamContext = stream_context_create($streamOptions);
$wsdl = 'file://' . dirname(__FILE__) . '/Service.wsdl';
try{
if ( file_get_contents( $wsdl ) ) {
$this->_soapClient = new SoapClient($wsdl,
array(
'soap_version' => SOAP_1_2,
'trace' => true,
'stream_context' => $streamContext
)
);
$auth = array('UserName' => $this->_username, 'Password' => $this->_password);
$header = new SoapHeader(self::WEB_SERVICE_URL, "WSUser", $auth);
$this->_soapClient->__setSoapHeaders(array($header));
}//if
}
catch(Exception $e){
echo "we couldnt connect". $e;
}
$this->_soapClient->GetUser();
I set the timeout to 0.01 to try and force the connection to timeout, but the request still seems to fire off. What am I doing wrong here?

I have had the same issues and have implemented solution !
I have implemented
SoapClient::__doRequest();
To allow multiple soap calls using
curl_multi_exec();
Have a look at this asynchronous-soap

Four solutions:
Use AJAX to do the SOAP -> Simplest SOAP example
Use AJAX to call a second PHP file on your server which does the SOAP (best solution imo)
Put the SOAP request to the end of your PHP file(s) (not the deluxe solution)
Use pcntl_fork() and do everything in a second process (I deprecate that, it might not work with every server configuration)
Depending on the way you implement this, PHP has plenty of timeout configurations,
for example socket_set_timeout(), or stream_set_timeout() (http://php.net/manual/en/function.stream-set-timeout.php)

Related

Not getting PHP soap api resonse on server for randome time

I am facing weired issue for soap api on my development and production server.
We have itegrated bunch of 3rd party soap API which are fetching details from 3rd party and displaying data on our site.It is working very well.Most of time APIs working perfectly.It happen in some random period of time soap api response becomes null and we get 0 in api response.We had discuss with 3rd party service about that issue and they had replied after check their log that, they are providing each and every response raising from our end.Can any one guide me does it code base issue or server base issue? and how to get rid of it as it is loosing client's business because of it.
Below are functinal of our WSDL calling from PHP soap function.
We send request for validation to 3rd party api, and store temp. security key on our server. And use this security key as token for each api.while this random glitch happen we does not get any response in that case. below is my soap code for call wsdl api.
$wsdl = 'URL';
$options = array(
'cache_wsdl' => 0,
'trace' => 1,
'stream_context' => stream_context_create(array(
'ssl' => array(
'verify_peer' => 0,
'verify_peer_name' => 0,
'allow_self_signed' => 1
)
)));
$soapCall = new SoapClient($wsdl,$options);
try {
$response = $soapCall->__soapCall("API_FUNCTION", array($params));
//Save records to log
$requestParamLogs = $soapCall->__getLastRequest();
$responseParamLogs = $soapCall->__getLastResponse();
}
catch (SoapFault $e) {
$requestParamLogs = $soapCall->__getLastRequest();
$responseParamLogs = $soapCall->__getLastResponse();
}
While we are facing such random issue on our deployment and production server, we do not get such issue in local server.
Note: We are getting response of each API in postman without issue all time.
I have tried google for it, but do not get anything suitable solution for my case so anyone having an idea, please guide me.

MQTT Subscribe with PHP to IBM Bluemix

I want to connect to IBM Bluemix through the MQTT protocol using PHP to subscribe to messages come from IoT Foundation.
I use this code:
<?php
require("../phpMQTT.php");
$config = array(
'org_id' => 't9m318',
'port' => '1883',
'app_id' => 'phpmqtt',
'iotf_api_key' => 'my api key',
'iotf_api_secret' => 'my api secret',
'device_id' => 'phpmqtt'
);
$config['server'] = $config['org_id'] .'.messaging.internetofthings.ibmcloud.com';
$config['client_id'] = 'a:' . $config['org_id'] . ':' .$config['app_id'];
$location = array();
// initialize client
$mqtt = new phpMQTT($config['server'], $config['port'], $config['client_id']);
$mqtt->debug = false;
// connect to broker
if(!$mqtt->connect(true, null, $config['iotf_api_key'], $config['iotf_api_secret'])){
echo 'ERROR: Could not connect to IoT cloud';
exit();
}
$topics['iot-2/type/+/id/phpmqtt/evt/+/fmt/json'] =
array("qos"=>0, "function"=>"procmsg");
$mqtt->subscribe($topics, 0);
// process messages
while ($mqtt->proc(true)) {
}
// disconnect
$mqtt->close();
function procmsg($topic, $msg) {
echo "Msg Recieved: $msg";
}
?>
But the browser show this message:
Fatal error: Maximum execution time of 30 seconds exceeded in /Library/WebServer/Documents/phpMQTT/phpMQTT.php on line 167
subscribe is not meant to run in the web browser as it has an infinite look, its best being run from the command line.
If you are using the subscribe method to receive messages you can look at persistent msgs and breaking out of the loop on msg receipt.
There is an example of how to use phpMQTT in the web browser in the file
web-app.php of this respository https://github.com/vvaswani/bluemix-iotf-device-tracker
You don't provide very much information about what you want to achieve by doing this; do you want to keep sending messages to the browser until the page is closed in the browser?
Server Sent Events or Websockets might be a better bet, and PHP might not be the best choice for this, because it uses up quite a lot of memory per connection (compared to node.js for example).
However if you just want to remove the 30 second PHP timeout, then you can use this function:
http://php.net/manual/en/function.set-time-limit.php
Or set max_execution_time in php.ini:
http://php.net/manual/en/info.configuration.php
Setting the maximum execution time to 0 should stop it from timing out.
But be warned that PHP and/or your webserver will have a limited number of concurrent HTTP connections.

How to speedup php soap client

I'm using a web service to send SMS in PHP. The code in like below:
$options = array(
'login' => 'yourusername',
'password' => 'yourpassword'
);
$client = new SoapClient('http://sms.hostiran.net/webservice/?WSDL', $options);
try
{
$messageId = $client->send(destination mobile number, 'test sms');
sleep(3);
print ($client->deliveryStatus($messageId));
var_dump($client->accountInfo());
}
catch (SoapFault $sf)
{
print $sf->faultcode."\n";
print $sf->faultstring."\n";
}
The problem is that when i run this code on a WAMP server, it runs rapidly.But when i use this code in an ubuntu server, the speed of running this code is very low.
Is there any configuration in php.ini to solve this problem ?
Thanks!
First, you need to remove sleep(3). That makes it take an extra 3 seconds.
Second, it looks like the sms provider is in Iran so it'd be best for you to get a web server in Iran.
As far as I know there is no reason why a Ubuntu server would be slower at SOAP than a Windows server
If you want to try and speed up the webpage what you should do is instead of running the SOAP request on page load you save the request to a database and then have a cron that runs every few minutes, pulls the requests out of the database, and makes the request.

php SOAP not sending certificate.pem

I can load in the wsdl, pull out the functions and data types just fine but when I try to call a function on the server I get a connection error. When I look at the soap data passed in the $request it doesn't contain any of the security certificate and no errors are generated.
My code looks like this:
// setup the transaction array
$header = array('local_cert' => "certificate.pem",
'logonUser' => "user_name",
'style' => SOAP_DOCUMENT,
'use' => SOAP_LITERAL,
'exceptions' => true,
'trace' => true);
// create the soap client, this will log us in
$client = new SoapClient($wsdl, $header);
try
{
$response = $client->getMessage($parameters);
}
catch (Exception $e)
{
dumpVars($client->__getLastRequest());
echo 'Caught exception: ', $e->getMessage(), "\n";
}
?>
So my question is this, what do I have to do to get the security certificate to be passed?
Thanks,
Pete
The purpose of local_cert in $header is not sending it in the SOAP call itself. It's only being used as an SSL client certificate. Also, according to this comment on php.net you need to read the file contents of the certificate in order to use it.
2 (small) things :
'logonUser' does not seem to be a valid option for the SoapClient constructor. If it is a required header for this service, consider using soapClient::setSoapHeaders. If it is a standard HTTP login param, use the 'login' key.
try to use the full path of the pem certificate, and make sure it is readable by php

How can i add exception?

I have a php site www.test.com.
In the index page of this site ,i am updating another site's(www.pgh.com) database by the following php code.
$url = "https://pgh.com/test.php?userID=".$userName. "&password=" .$password ;
$response = file_get_contents($url);
But,now the site www.pgh.com is down.So it also affecting my site 'www.test.com'.
So how can i add some exception or something else to this code,so that my site should work if other site is down
$response = file_get_contents($url);
if(!$response)
{
//Return error
}
From the PHP manual
Adding a timeout:
$ctx = stream_context_create(array(
'http' => array(
'timeout' => 1
)
)
);
file_get_contents("http://example.com/", 0, $ctx);
file_get_contents returns false on fail.
You have two options:
Add a timeout to the file_get_contents call using stream_get_context() (The manual has good examples; Docs for the timeout parameter here). This is not perfect, as even a one second's timeout will cause a notable pause when loading the page.
More complex but better: Use a caching mechanism. Do the file_get_contents request in a separate script that gets called frequently (e.g. every 15 minutes) using a cron job (if you have access to one). Write the result to a local file, which your actual script will read.

Categories