PHP is connected to SOAP between NuSOAP and I can recieve data from PHP. After getting data, I get timeout error because of data size is huge which is received. You can see xdebug print out on below.I can run same service using PHP native SOAP command.
http://s15.postimg.org/c9491lf1n/2015_03_08_02_07_10.jpg
I am using following settings. I can not get a solution about the above error although I increased maximum limit as possible as much.
ini_set('memory_limit', "512M");
ini_set('max_execution_time', 60000); //x saniye
ini_set("display_errors", 1);
ini_set("max_input_time ", 6000);
I am waiting your solution about this issue urgently. Thank for your support.
Edit:
My NuSOAP client function:
function nusoapCall($method,$params,$returnType="array"){
global $WSDLURL,$debugMode;
require_once('tools/nusoap/nusoap.php');
$soapClient = new nusoap_client($WSDLURL, 'wsdl');
$soapClient->soap_defencoding = 'UTF-8';
$soapClient->decode_utf8 = false;
$soapClient->setUseCURL(true);
//$soapClient->loadWSDL();
$soapClient->setCurlOption(CURLOPT_CONNECTTIMEOUT, 60);
if($debugMode == 1){
$soapClient->debug_flag = false;
}
$tResult = $soapClient->call( $method,$params);
if($returnType=="object"){
$tResult = array_to_object($tResult);
}
$soapError = $soapClient->getError();
echo $soapClient->getDebug();
if (!empty($soapError)) {
$errorMessage = 'Nusoap object creation failed: ' . $soapError;
throw new Exception($errorMessage);
return false;
}else{
return $tResult;
}
}
Related
I use Node.js to run STOMP over WebSocket because it supports custom headers. When HTTP handshake, the server needs a cookie to check auth, not the token in the address.
As PHPer, I want to use this in PHP, but search google for a long time and found no way. can anyone help?
STOMP is not limited to Node.js, or Java, etc. There are
a STOMP PECL extension for PHP,
PHP STOMP libraries, e.g Stomp-PHP,
and general messaging libraries that support STOMP,
e.g. Enqueue's STOMP transport layer, or Laravel-Queue
Regarding your specific scenario, it's hard to come up with a straight-up answer without knowing more details but here is an example from the stomp-php library samples hat sets a custom header:
use Stomp\Client;
use Stomp\SimpleStomp;
use Stomp\Transport\Map;
// make a connection
$client = new Client('tcp://localhost:61613');
$stomp = new SimpleStomp($client);
// send a message to the queue
$body = array('city' => 'Belgrade', 'name' => 'Dejan');
$header = array();
$header['transformation'] = 'jms-map-json';
$mapMessage = new Map($body, $header);
$client->send('/queue/test', $mapMessage);
echo 'Sending array: ';
print_r($body);
$stomp->subscribe('/queue/test', 'transform-test', 'client', null, ['transformation' => 'jms-map-json']);
/** #var Map $msg */
$msg = $stomp->read();
// extract
if ($msg != null) {
echo 'Received array: ';
print_r($msg->map);
// mark the message as received in the queue
$stomp->ack($msg);
} else {
echo "Failed to receive a message\n";
}
you need a websocket stream wrapper if you want to connect using a protocol
You can use php-stomp-frame
https://github.com/jeeinn/php-stomp-frame
composer require jeeinn/php-stomp-frame
public function getStompMessage(): array
{
$stompFrame = new Frame();
$connectFrame = $stompFrame->setLogin($this->ss['login'], $this->ss['password'])
->setHeartBeat(0, 10000)->getConnect();
$subscribeFrame = $stompFrame->getSubscribe($this->ss['queue']);
$client = new Client($this->ss['host']);
$client->text($connectFrame);
$client->text($subscribeFrame);
$response = [];
$i = 0;
while ($i < 3) {
sleep(5);
try {
$message = $client->receive();
if (empty($message) || in_array($message, self::BYTE)) {
$i++;
continue;
}
$parsed = $stompFrame->parser($message);
if ($parsed['command'] == $this::STOMP_COMMAND_ERROR) {
$this->logger($this::INFO, 'STOMP return with ERROR command:', $parsed['body']);
$client->close();
break;
}
if (($parsed['command'] == $this::STOMP_COMMAND_MESSAGE) || ($parsed['body'])) {
return json_decode($parsed['body'], true);
}
} catch (Exception $e) {
$this->logger($this::ERROR, 'STOMP error', (array)$e->getMessage());
}
$i++;
}
return $response;
}
I am using the php ssh2 methods to establish a connection to a server and transmit a string of ~39Kb. However, after 32Kb the transmission stops with an exception:
ErrorException: ssh2_exec(): Unable to request command execution on remote host in /var/www/xxx/xxxSSH.php:36
Is there an artificial limit on how many bytes can be transmitted in a session and if so, how can I change the limit?
UPDATE
Here's the method producing the error:
public function exec($cmd)
{
if (!($stream = ssh2_exec($this->connection, $cmd))) {
throw new Exception('SSH command failed');
}
stream_set_blocking($stream, true);
$data = "";
while ($buf = fread($stream, 4096)) {
$data .= $buf;
}
fclose($stream);
return $data;
}
$cmd contains the string that seems to cause the trouble. What it does is call echo '$extremelyLongString' > /etc/someconfig.cfg
I am running distributed job distribution through gearman. I am trying to convert 1000 pdf files of size 10 MB each. I am able to set it up and get the pdf files encoded.
I have the following code:
gearman_client.php (only to initialize)
<?php
class gearman_client{
static $timeout = 5000;
private static function addServerToCLient($client, $server){
$added = 0;
$client->setTimeout(self::$timeout);
$server = explode(':', $server);
$job_server = $server[0];
if(array_key_exists(1, $server))
$job_server_port = $server[1];
else
$job_server_port = 4730; //default port
try{
$added = $client->addServer($job_server, $job_server_port);
}
catch(GearmanException $e){
error_log(sprintf("GearmanException: %s .Error adding Gearman Server: %s, port: %s",$e->getMessage(), $job_server, $job_server_port), false);
}
return $added;
}
public static function initialize(){
$client = null;
$servers = explode(',', GEARMAN_JOB_SERVERS);
$added = 0;
//To accomodate Gearman bug
$flag = 0;
foreach($servers as $server){
if(!$flag){
unset($client);
$client = new GearmanClient();
}
$added = self::addServerToCLient($client, $server);
if($added)
$flag = 1;
}
if($flag)
return $client;
return 0;
}
}
Gearman client
$gmclient = gearman_client::initialize();
if(!$gmclient){
$this->error("Gearman server error","Could not create a gearman client object with a running Gearman Server");
return;
}
$pdfdata = array(
"id_host" => $this->id_host,
"id_vhost" => $this->id_vhost,
"id_contents" => $id_contents
);
$job_handle = $gmclient->doBackground("pdf_convert", json_encode($pdfdata));
if ($gmclient->returnCode() != GEARMAN_SUCCESS){
error_log("Gearman client: Bad Return code. Error while submitting background job");
}
Gearman worker
$worker = new GearmanWorker();
$worker->addServer("192.0.1.118");
$worker->addFunction("pdf_convert", function(GearmanJob $job) {
$workload = json_decode($job->workload());
$id_host = $workload->id_host;
$id_vhost = $workload->id_vhost;
$id_contents = $workload->id_contents;
contents_path($id_host, $id_vhost, $id_contents);
pdf($id_host, $id_vhost, $id_contents);
// You would then, of course, actually call this:
//mail($workload->email, $workload->subject, $workload->body);
});
while ($worker->work());
everything seems to be working well. However, I see that even though I start multiple instances of gearman worker, there is only one worker which is always busy(which I can see through the telnet interface).
If I introduce a sleep(30) in the worker code, then I start to see other workers taking up jobs.
Is this normal behavior?
I'm getting an error message when making a call to an xBase++ based web server that is acting as a web service (not using WSDL) when trying to make a soapclient call to it using NuSoap 1.94 with PHP 5.2.17. This exact same code works with NuSOAP 1.94 on PHP 4. Any ideas or help would be appreciated!
Note (I had to remove the https:// part of the addresses from the error message below - I was getting an error posting saying I needed 10 reputation to post 2 links or more)
Thanks,
Salar
Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from 'xxx.xxx.com:55055' : failed to load external entity "xxx.xxx.com:55055" in /hsphere/local/home/xxx/xxx.com/phpinvent/inc/functions/xmsg.php:34 Stack trace: #0 /hsphere/local/home/xxx/xxx.com/phpinvent/inc/functions/xmsg.php(34): SoapClient->SoapClient('https://xxx.xxx...') #1 /hsphere/local/home/xxx/xxx.com/phpinvent/xmsgtest.php(15): XMsg('LOGIN', Array) #2 {main} thrown in /hsphere/local/home/xxx/xxx.com/phpinvent/inc/functions/xmsg.php on line 34
Here's the code of my test page, and the xmsg function:
<?php
ini_set('display_errors', 'On');
ini_set('default_socket_timeout', 300);
error_reporting(E_ERROR | E_WARNING | E_PARSE);
// include configuration
require_once('inc/config.php');
require_once('inc/nusoap/nusoap.php'); // include the NuSOAP classes
$xmsg_param[0][0] = "userid";
$xmsg_param[0][1] = "TEST";
$xmsg_param[1][0] = "password";
$xmsg_param[1][1] = "TEST";
$result = XMsg("LOGIN", $xmsg_param);
echo("<br>resulttxt: ".$result['xmsg_resulttxt']);
echo("<br>Sessionid: ".$result['sessionid']);
?>
<?php
// XMsg *************************************************************************
// This function is used to send a message through the robust, connectionless message system
function XMsg($xm_type, $xm_parameters, $xm_target = XMSG_DEFAULT_GATEWAY, $xm_mode = XMSG_DEFAULT_MODE)
{
// Parameters:
// xm_type - C - mandatory – type of message being sent
// xm_parameters - A - optional - 2 dimensional array of name/value pairs that will be sent to the target with the message
// xm_target - C - optional - target - currently supports only URLs of AutoMate agents - defaults to gateway
// xm_mode - C - optional - tokens that allow for modification of the message - currently defaults to #SOAP# to send via SOAP
// Returns:
// xm_result - A - array of name/value pairs returned from the target in same format as xm_target
$xm_SOAPagent = ''; // SOAP Envelope Object - Request
$xm_SOAPresult = ''; // SOAP Envelope Object - Response
$xm_SOAPclass = '';
$xm_retrynum = 0; // Number of retries attempted
$xm_retry = true; // Continue retrying?
$xm_result = Array(); // Array of results returned by XMsg
$xm_numparams = 0; // Number of parameters passed to XMsg
$xm_I = 0; // FOR Loop Counter
// Initialize Parameters
$xm_parameters = (gettype($xm_parameters) == "array" ? $xm_parameters : array());
// check if mandatory parameters are passed
// xm_type must be character and not empty
if (gettype($xm_type)=="string" && !empty($xm_type)) {
switch($xm_mode)
{
case "SOAP":
// open SOAP envelope and initialize
echo("calling xm_target: ".$xm_target."<br>");
$soapclient = new soapclient($xm_target);
$soapparam = array();
// create and pass xmsg structure - NOTE: this section is specialized to PHP
$soapparam['xmsg_id'] = '';
$soapparam['xmsg_source'] = '';
$soapparam['xmsg_target'] = $xm_target;
$soapparam['xmsg_session'] = $_SESSION['SESSIONID'];
$soapparam['xmsg_userid'] = $_SESSION['USERID'];
$soapparam['xmsg_websessid'] = session_id();
$soapparam['xmsg_ip'] = $_SERVER['REMOTE_ADDR'];
$soapparam['xmsg_status'] = 'SENT';
$soapparam['xmsg_type'] = $xm_type;
$soapparam['xmsg_result'] = '';
$soapparam['xmsg_resulttxt'] = '';
$soapparam['xmsg_date'] = date("m/d/y");
$soapparam['xmsg_time'] = date("H:i:s");
$soapparam['xmsg_datereceive'] = '';
$soapparam['xmsg_timereceive'] = '';
$soapparam['xmsg_dateresponse'] = '';
$soapparam['xmsg_timeresponse'] = '';
// count parameters and add to SOAP Envelope
$xm_numparams = count($xm_parameters);
for ($xm_I = 0; $xm_I < $xm_numparams; $xm_I++) {
echo("setting soapparam[".$xm_parameters[$xm_I][0]."] to :".$xm_parameters[$xm_I][1]);
$soapparam[$xm_parameters[$xm_I][0]] = $xm_parameters[$xm_I][1];
}
// SOAP retry loop start - retry until xm_retry is false - set to false when call succeeds or max # retries exceeded
do {
// run remote SOAP call for RemoteCall as specified in
$xm_result = $soapclient->call('XMsg',$soapparam);
// check for fault
echo ("Fault: ".$xm_result['FAULT']."<br>");
echo ("1 Faultcode: ".$xm_result['faultcode']."<br>");
if (empty($xm_result['faultcode'])) {
echo('<hr>'.'<pre>' . htmlspecialchars($soapclient->response, ENT_QUOTES) . '</pre>');
echo('<hr>'.'<pre>' . htmlspecialchars($soapclient->debug_str, ENT_QUOTES) . '</pre>');
$xm_retry = false;
// update status / response date / time
$xm_result['xmsg_status'] = "RECEIVED";
$xm_result['xmsg_dateresponse'] = date("m/d/y");
$xm_result['xmsg_timeresponse'] = date("H:i:s");
} else {
echo("2 faultcode: ".$xm_result['faultcode']);
}
// SOAP Call retry handling
if ($xm_retry) {
// increase the SOAP comm retry counter to count the number of retries made
$xm_retrynum++;
// check if the maximum number of retries has been reached
if ($xm_retrynum <= XMSG_NUMRETRY) {
sleep(XMSG_RETRYDELAY); // delay for set number of seconds
} else {
$xm_retry = false;
}
}
} while ($xm_retry);
break;
default:
// no other message type handling currently
}
}
}
return $xm_result;
// XMsg *************************************************************************
This is quite simple. Your web server can't see the location the WSDL is hosted at. Can you hit the location if you copy the WSDL url and paste it into your browser? You should check that the URL you are using is correct, and whether your web server can even see that location. If not you will need to remedy that before it will work.
We're using a modified version of easy-apns for sending our push messages. With the enhanced push message format the apple server responds if an error occurs, and does nothing if everything goes well.
The problem is that we have to wait for an error a certain amount of time after each message has been sent. For example if we receive no response after 1 second, we assume everything went ok.
With 20000 push messages, this takes far too long. Is there any way I can listen for errors in a faster way? For example sending to 1000 devices and then listen for errors? What happens if the connection gets closed, can I still read the error response?
Ideal would be some kind of asynchronous writing and reading, but I think that's not possible.
Here's the corresponding code:
$fp = $this->connect();
$expiry = time()+60*60;
// construct message
$msg = chr(1).pack("N",$batchid).pack("N",$expiry).pack("n",32).pack('H*',$devicetoken).pack("n",strlen($payload)).$payload;
// send message to Apple
$fwrite = fwrite($fp, $msg);
if(!$fwrite) {
// connection has been closed
$this->disconnect();
throw new Exception("Connection closed");
} else {
// read response from Apple
// Timeout. 1 million micro seconds = 1 second
$tv_sec = 1;
$tv_usec = 0;
$r = array($fp);
$we = null; // Temporaries. "Only variables can be passed as reference."
// PROBLEM: this method waits for $tv_sec seconds for a response
$numChanged = stream_select($r, $we, $we, $tv_sec, $tv_usec);
if( $numChanged === false ) {
throw new Exception("Failed selecting stream to read.");
} elseif ( $numChanged > 0 ) {
$command = ord( fread($fp, 1) );
$status = ord( fread($fp, 1) );
$identifier = implode('', unpack("N", fread($fp, 4)));
if( $status > 0 ) {
// The socket has also been closed. Cause reopening in the loop outside.
$this->disconnect();
throw new MessageException("APNS responded with status $status: {$this->statusDesc[$status]} ($devicetoken).".microtime(), $status);
} else {
// unknown response, assume ok
}
} else {
// no response, assume ok
}
}