Я создаю собственное приложение C2DM прямо сейчас. Сначала я начал с небольшого приложения для Android, чтобы проверить функцию push. И он работает, если я просто вызываю команду curl с правильными настройками в моей оболочке.
Теперь для части сервера я хотел использовать PHP, но, как кажется, я делаю что-то неправильно, так как всегда получаю сообщение об ошибке 401, когда пытаюсь отправить сообщение клиенту. Прежде всего код состоит из двух частей. Первый запрос curl запрашивает маркер сервера. Это работает, я получаю реальный ответ от google с действующим токеном!
Второй запрос на завивки заканчивается сообщением об ошибке 401. Любые идеи, что я делаю неправильно?
$post_params = array ( "Email" => $MY_GOOGLE_ACC, "Passwd" => $MY_GOOGLE_PWD, "accountType"=>"GOOGLE", "source=" . $MY_GOOGLE_SRC, "service=ac2dm" ); $first = true; $data_msg = ""; foreach ($post_params as $key => $value) { if ($first) $first = false; else $data_msg .= "&"; $data_msg .= urlencode($key) ."=". urlencode($value); } $x = curl_init("https://www.google.com/accounts/ClientLogin"); curl_setopt($x, CURLOPT_HEADER, 1); curl_setopt($x, CURLOPT_POST, 1); curl_setopt($x, CURLOPT_POSTFIELDS, $data_msg); curl_setopt($x, CURLOPT_RETURNTRANSFER, 1); $data = curl_exec($x); curl_close($x); $response = $data; $authKey = trim(substr($response, 4+strpos($response, "SID="))); echo $authKey; $collapse_key = 'something'; $post_params = array ( "registration_id" => $DEVICE_TOKEN, "collapse_key" => $collapse_key, "data.payload"=>"cakephp" ); $first = true; $data_msg = ""; foreach ($post_params as $key => $value) { if ($first) $first = false; else $data_msg .= "&"; $data_msg .= urlencode($key) ."=". urlencode($value); } $size=strlen($data_msg); $x = curl_init("https://android.apis.google.com/c2dm/send"); curl_setopt($x, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded', 'Content-Length:'. $size, 'Authorization: GoogleLogin auth=' . $authKey)); curl_setopt($x, CURLOPT_HEADER, 1); curl_setopt($x, CURLOPT_POST, 1); curl_setopt($x, CURLOPT_POSTFIELDS, $data_msg); curl_setopt($x, CURLOPT_RETURNTRANSFER, 1); $data = curl_exec($x); curl_close($x); $response = $data;
Пример использования массива key'd с помощью curl. Это в значительной степени точный код, который у меня работает (с незначительными изменениями для ясности).
$headers = array('Authorization: GoogleLogin auth=' . $authcode); $data = array( 'registration_id' => $device_registration_id, 'collapse_key' => 'ck_' . $device_id, 'data.arg' => 'arrrrghhh' ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://android.apis.google.com/c2dm/send"); if($headers) curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_exec($ch);
$ authcode – это идентификатор SID, возвращаемый ClientLogin. $ device_registration_id – это идентификатор регистрации, который клиентское приложение на телефоне предоставило нам, когда мы сделали C2DM_REGISTER.
Надеюсь, это поможет.
Попробуйте зарегистрировать свое приложение здесь . У меня такая же проблема.
Я не совсем уверен, что здесь происходит, но вот несколько различий, которые я заметил с моего сервера приложений, который отлично работает.
В вашем вызове curl_setopt для CURLOPT_HTTPHEADER между длиной содержимого и размером нет пробела. Это «не должно вызывать проблемы, но я видел, что веб-серверы получают tempremental над глупыми вещами, как раньше.
Кроме того, CURLOPT_POSTFIELDS является строкой, тогда как я посылаю мой как массив key'd.
Помимо этого я выгляжу так же, как и мой рабочий код.