My server sents GCM request to the GCM api for the push notification.The push notification works fine for some couple of push notification, after that the curl function which is making the request is getting timed out with the following error
"Curl failed: Failed to connect to android.googleapis.com port 443: Connection timed out"
without any response.But the response code is 200Ok.
But again after sometime if I try it will sent the notification with a proper success response and if I try sending for sometime, to different devices it again hangs and shows the above message.
I have opened port 5228, 5229, and 5230 on my firewall.
Why does this happen.I can't figure why it is happening like this.
This is the code Im using
$headers = array(
'Authorization: key=' . $this->serverApiKey,
'Content-Type: application/json'
);
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt( $ch, CURLOPT_URL, $this->url );
curl_setopt($ch, CURLOPT_PORT, 443);
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $fields ) );
// Avoids problem with https certificate
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false);
// Execute post
$result = curl_exec($ch);
Please help me to find a solution for this.
This seems to be more of a firewall/proxyserver issue.. Make sure you have port 443 open in your server. Make use of the ping and the curl command to verify this.
See this Stack Overflow issue to get more insight.
Related
I am tasked with building an API to receive inbound XML data. On my client, I have this code.
$url = "http://stackoverflow.com";
$xml = '<?xml version="1.0" encoding="UTF-8"?><Request PartnerID="asasdsadsa" Type="TrackSearch"> <TrackSearch> <Title>love</Title> <Tags> <MainGenre>Blues</MainGenre> </Tags> <Page Number="1" Size="20"/> </TrackSearch> </Request>';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));
curl_setopt( $ch, CURLOPT_POSTFIELDS, "xml=".$payload );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
$request = curl_exec($ch);
curl_close($ch);
On my remote server, I have this code
function TransmitRx()
{
$xml = trim(file_get_contents('php://input'));
file_put_contents("newStandard/".rand(100,500)."received.xml", $xml);
}
//Listen for inbound data
TransmitRx()
If I open up the server endpoint URL, there is an empty file saved. I don't know why. But when I run the client-side script. I get nothing. No errors. Nothing.
I have looked at several of the pages here and every one of them has a similar cURL statement to send data.
Why am I not receiving any post data at the API endpoint?
I have been unsuccessful at any information via the WWW.
UPDATE
Final Code that works:
function get_url($request_url, $payload)
{
$headers = [
"Access-Control-Allow-Origin: *",
"Content-type: text/xml",
"Content-length: " . strlen($payload),
"Connection: close",
];
$data = ['xml' => $payload];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $request_url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$response = curl_exec($ch) or die(curl_error($ch));;
if (curl_errno($ch)) {
print curl_error($ch);
} else {
curl_close($ch);
}
return $response;
}
$request_url = 'https://stackoverflow.com/posts';
$response = get_url($request_url, $payload);
I wish I knew for sure what caused it to start working. I was reading this page last.
https://www.php.net/manual/en/curlfile.construct.php
Okay, so if adding the lines I suggested to disable certification / peer validation enabled the process to work, then that just means the remote server is using an SSL certificate that is not trusted by cURL.
Those lines are NOT the final fix. You never want to disable SSL validation in a real environment. I only suggested you temporarily disable them to see if that was truly the problem. If you leave them disabled, then you are leaving your code vulnerable to man-in-the-middle (MITM) attacks.
The correct fix is usually to point cURL at an updated CA bundle. The official cURL website graciously provides these here:
https://curl.haxx.se/docs/caextract.html
The process is that you download the CA bundle file and put it somewhere where your script can find it, and then add this curl option:
curl_setopt ($ch, CURLOPT_CAINFO, "full path to the CA bundle file.pem");
If the remote server's certificate came from any of the major CA vendors out there, this should be all you need to do.
If the remote server's certificate is self-signed or something then you might need to download the specific CA certificate and any supporting intermediate CA certificates and tell cURL to find them.
I have bought a linux server from Godaddy . I tested to connect and get response from remote server , but it says CURL Failed . Also , it doesn't work on Node app too .
Here is the PHP Code :
<?php
$url = 'http://dev.api/pay';
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, "<xml>here</xml>" );
curl_setopt($ch, CURLOPT_PORT, '9085');
$result = curl_exec($ch);
$output = curl_getinfo($ch);
echo "<pre>";
var_dump($output);
echo "</pre>";
curl_close($ch);
var_dump($result);
. Actually this code is working on localhost , but it doesn't work when accessed from the server. If the outgoing connection is being blocked from the server's firewall i rented , how can i disable it or allow that port i intended to use only ?
Do you have root access?
if so, use iptables to remove outgoing connection block.
If you do not have root acces, your host just does not allow outbound connections and there is nothing you can do about it.
I am trying to send push notification some android devices using the registration ids which is stored in database table.
Here is my code
//message and title for push notification
$msg=$_POST['message'];
$title=$_POST['title'];
$result=$connect->prepare("SELECT `push_id` FROM `user_devices`");
$result->execute();
//get registration id's
$ids=$result->fetchAll(PDO::FETCH_COLUMN);
$key="XXXXX";
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' =>$ids,
'data' => array( "message" =>$msg,"title"=>$title,"soundname"=>"beep.wav" ),
);
$headers = array(
'Authorization: key=' . $key,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $fields ) );
$res = curl_exec($ch);
if($res === false)
echo 'Curl failed ' .curl_error();
}
I am getting curl Failed error message but didn't see anything from curl_error().
UPDATE
I am running this script from windows server which is hosted in azure cloud service.
Now i am run this from linux based server its works fine,but it didnt work in windows server.
You are probably getting error due to SSL (in your url https) issue. You have to configure your curl to handle secured request. You can find a hints from here: Configuring cURL for SSL
You are not getting the error msg because you need to print it like below:
echo 'Curl failed ' .curl_error($ch); // you are missing $ch here
Alternately you can run your curl with verbose enabled to see the things happening with your curl request!
curl_setopt( $ch, CURLOPT_VERBOSE, true );
It was the problem of My SSL Certificate.
Solved using one line code
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); is placed in after curl_init.
NOTE
This is a temporary solution.Actual way is generate an SSl certificate.
I used mark nutter phonegap plugin for GCM and I successfully get the registration id back from server
here is php script that I use
<?php
// Replace with real server API key from Google APIs
$apiKey = "AIzaSyC7wzEjjMaOGLYp8_w3USftv_3lI-qCdZ4";
// Replace with real client registration IDs
$registrationIDs = array( "APA91bFt3slFE96jaB5qnoD5gR0TCwsxe5StEGyrECR0umYviG0cfG1JNnFxYqP1ERr1RoWc38rsuWjRUx5SZ7cgUNG9-mQ4mSsY8_XQLquft5DLnqWcLCEB2wtQpfA6EAp5OQmOWzpUZU5bohfG4sfLWNUco7XxXg");
// Message to be sent
$message = "hi SOurabh";
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registrationIDs,
'data' => array( "message" => $message ),
);
$headers = array(
'Authorization: key=' . $apiKey,
'Content-Type: application/json'
);
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
//curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $fields ) );
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// curl_setopt($ch, CURLOPT_POST, true);
// curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode( $fields ));
// Execute post
$result = curl_exec($ch);
// Close connection
curl_close($ch);
echo $result;
//print_r($result);
//var_dump($result);
?>
I do not know much about php I used thi just to test notifications
and I get following message when I run this
{"multicast_id":9187695352946100598,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"MismatchSenderId"}]}
any idea why do I get this?
or any other way to test the app?
Does the project ID that you used on the project match the one shown on the google console ?
https://code.google.com/apis/console/#project:?????
Does the API key belong under 'server apps' on the google GCM page ? Your phone must also have a valid registered google account to receive notifications.
I started to use your php-script to debug push notification on my app.
First time I received the same error.
Updating SENDER_ID value to Google API Console App Project ID in Android client application fixed the issue - messages are delivered successfully.
Searching for some info about how to send notifications using GCM but with PHP instead of servlets, i found this: GCM with PHP (Google Cloud Messaging)
I tested the working code of the responses of these questions, also i created a Key for browser apps (with referers), and i give permissions to this ip: .mywebsite.com/ (te php file is on this url: "http://www.mywebsite.com/~jma/cHtml5/cap/kk.php")
But i'm getting this response: Unauthorized Error 401
What i'm doing wrong?
this is the php file:
<?php
// Replace with real server API key from Google APIs
$apiKey = "fictional key";
// Replace with real client registration IDs
$registrationIDs = array( "APA91asdasdSDGGS232S13S4213abGqiNhCIXKjlxrkUYe_xTgTacNGB5n16b380XDd8i_9HpKGRHkvm8DDet4_WK3zumjDEKkTRWLgPS7kO-BrKzWz7eWFQaDD9PJ8zA6hlSqL9_zH21P8K22ktGKmo_VIF6YAdU9ejJovrKBTpgQktYkBZBf9Zw","APAasdasd32423dADFG91bHYYxYB7bFiX5ltbJt6A-4MBiNg7l4RS4Bqf3jIfYviaaUfZ810XJo2o66DY9-jdeJk_JR8FIZCyrmCv-eu_WLkGZ8KaoHgEDR_16H2QPm98uHpe1MjKVXbzYc4J89WMmcIrl5tHhWQnIQNzaI6Zp6yyFUNUQ");
// Message to be sent
$message = "Test Notificación PHP";
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registrationIDs,
'data' => array( "message" => $message ),
);
$headers = array(
'Authorization: key=' . $apiKey,
'Content-Type: application/json'
);
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
//curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $fields ) );
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//curl_setopt($ch, CURLOPT_POST, true);
//curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode( $fields ));
// Execute post
$result = curl_exec($ch);
// Close connection
curl_close($ch);
echo $result;
//print_r($result);
//var_dump($result);
?>
Solved!!!
you must use Key for server apps (with IP locking) instead of browser key
:)
You need to use the key for server apps in the field of API key in your server side coding.
While creating the server key don't enter anything inside IP address field.