Intereting Posts
Android App – Как сохранить рисунок растрового изображения на холсте как изображение? Проверить код? Стратегия загрузки асинхронных изображений ListView Как программно добавлять представления в представления Как отключить прием GPS-сигнала TextToSpeech с API 21 Несколько вызовов в AlarmManager.setRepeating предоставляют такие же значения Intent / PendingIntent, но я предоставлял разные Как отключить сообщение тоста для тостов, которое иногда появляется с помощью элементов управления масштабированием в WebView? Как изменить цвет по диалогу Android Создание формы треугольника с использованием определений xml? Каков самый простой способ рисовать текстуру с помощью OpenGL ES? Android: Как я могу проверить определенный элемент в проверенном ListView? Можно ли использовать один файл ключей для подписи двух разных приложений? Работа с unicode , как избавиться? Android / Java Ошибка Phonegap android sdk build.xml: 950: null: 1 DrawerLayout изменить чувствительность?

Отправка сообщения GCM (серверная сторона) часто терпит неудачу – но далеко не всегда

Я использую сервис Google Cloud Messaging (GCM) для своего приложения для Android. Я реализовал его в соответствии со всеми правилами, и он работает. Ну, почти.

Чаще всего, я бы сказал, что в 60-70% случаев я могу успешно отправить сообщение GCM с моего сервера, используя webservice, как описано на веб-страницах google.

Обычно я получаю следующий ответ от webservice, который указывает, что я успешно отправил сообщение GCM:

{ "multicast_id":8378088572050307085, "success":1, "failure":0, "canonical_ids":0, "results": [ { "message_id":"0:1363080282442710%7c4250c100000031" } ] } 

Это говорит: все ОК, сообщение отправлено.

Однако во многих случаях я получаю сообщение об ошибке HTTP при вызове webservice, в котором говорится:

Не удалось прочитать данные из транспортного соединения. Установленное соединение было прервано программным обеспечением вашего хост-компьютера.

Это сообщение .NET, чтобы сообщить мне, что вызов веб-службы (с использованием HttpWebRequest и POST) не удался.

Это некоторые сообщения журнала, которые показывают проблему:

Введите описание изображения здесь

Это код, который я использую для вызова WS:

 public static string SendMessage(string registrationId, string command, string extra, bool retry) { try { HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://android.googleapis.com/gcm/send"); request.Method = PostWebRequest; request.KeepAlive = false; GCMPostPacket json = new GCMPostPacket() { collapse_key = "1", time_to_live = 60, registration_ids = new List<string>(new string[] { registrationId }), data = new GcmData() { message = command, misc = extra } }; // Converting to JSON string string jsonString = SICJsonProtocol.JSONHelper.Serialize<GCMPostPacket>(json); byte[] byteArray = Encoding.UTF8.GetBytes(jsonString); request.ContentType = "application/json"; request.ContentLength = byteArray.Length; request.ProtocolVersion = HttpVersion.Version10; request.Headers.Add(HttpRequestHeader.Authorization, "key=" + "MyVerySecretKey"); Stream dataStream = request.GetRequestStream(); dataStream.Write(byteArray, 0, byteArray.Length); dataStream.Close(); using (WebResponse response = request.GetResponse()) { HttpStatusCode responseCode = ((HttpWebResponse)response).StatusCode; if (responseCode.Equals(HttpStatusCode.Unauthorized) || responseCode.Equals(HttpStatusCode.Forbidden)) { Console.WriteLine("Unauthorized - need new token"); } else if (!responseCode.Equals(HttpStatusCode.OK)) { Console.WriteLine("Response from web service not OK :"); Console.WriteLine(((HttpWebResponse)response).StatusDescription); } StreamReader reader = new StreamReader(response.GetResponseStream()); string responseLine = reader.ReadLine(); Console.WriteLine("************************"); Console.WriteLine("GCM send: " + responseCode + " | " + responseLine); // This is the log shown in the image above SRef.main.gui.ServiceUpdate("GCM send: " + responseCode + " | " + responseLine); reader.Close(); response.Close(); return responseLine; } } catch (Exception e) { // This is the log shown in the image above SRef.main.gui.ServiceUpdate("Failed send GCM, " + (retry ? "retrying in 20 sec" : "not retrying") + ". Error=" + e.Message); if (retry) { System.Threading.ThreadPool.QueueUserWorkItem(delegate(object obj) { try { System.Threading.Thread.Sleep(20000); SendMessage(registrationId, command, extra, false); } catch (Exception ex) { } }); } return null; } } 

Может ли кто-нибудь увидеть, что я делаю что-то неправильно, или если я вообще что-то упускаю?

Solutions Collecting From Web of "Отправка сообщения GCM (серверная сторона) часто терпит неудачу – но далеко не всегда"

Не удалось прочитать данные из транспортного соединения. Установленное соединение было прервано программным обеспечением вашего хост-компьютера.

Эта ошибка не имеет ничего общего с GCM API. Это означает, что ваш клиент попытался связаться с веб-службой, но соединение, которое было установлено, было отключено на одном из сетевых уровней. В зависимости от того, где вы получите эту ошибку и сообщение об ошибке, это может означать несколько вещей.

  1. Ваш клиент решил прервать соединение из-за таймаута сокета. Увеличьте время ожидания чтения / сокета клиента, чтобы улучшить ситуацию.

  2. Балансировщик нагрузки, который находится между клиентом и сервером, сбросил соединение. Каждая сторона думает, что другая потеряла соединение.

Тайм-ауты в сети обычно являются огромной болью, поскольку никогда не было ясно, где было отключено соединение, и кто его сбросил. Если увеличение тайм-аутов не помогает, я предлагаю отправить запросы через прокси-сервер, который может обнюхать трафик HTTPS (charles / TCPMON) или использовать Wireshark, чтобы узнать, какие пакеты удаляются.

В вашем приложении Android также есть мониторинг GCM, который можно включить на вкладке Статистика. Проверьте, сообщает ли API GCM сообщение о состоянии, отличное от 200 OK на этом графике. Это поможет сузить проблему дальше. Если нет сообщений о кодах статуса, отличных от 200, это означает, что GCM никогда не получал ваши запросы API.