I have an .Net windows service that sends GCM push notifications via https://android.googleapis.com/gcm/send.
The service periodically sends batches of approximately 10,000 messages at a rate of 10 / second. With each batch, 5 - 10 of the messages will cause a "502 Bad Gateway" response. The messages that generate the 502 always go through with a second try.
Is this normal? Could I be sending too many messages too quickly?
According to the GCM guide, all 5xx error codes should be treated as temporary errors, and requests that get these errors should be retried :
5xx Errors in the 500-599 range (such as 500 or 503) indicate that there was an internal error in the GCM server while trying to process the request, or that the server is temporarily unavailable (for example, because of timeouts). Sender must retry later, honoring any Retry-After header included in the response. Application servers must implement exponential back-off.
I don't think 10 messages a second is too quick. As long as your code handles this error and retries, I don't think there should be any problem.
Related
I have enable stream management in both side client or server. I have two users A and B. Both users are online.Then user A suddenly lose his connection. but A user still appear online on user B and as well as on server. During that time user B sending message on user A. Those message are not lost but when user A is appear online again it will receive those message after 2-3 minute.and i will get message stanza on Offline storage and delivery receipt i will got on SM storage.This issue same occur on one to one chat and mucLight. have i need to customized any mongooseIM modules. Please guide me why users received delay message when their are lost his connection. is it possible to changed SM storage to offline storage(MAM). here's link for same issue i have found same issue on this link (https://www.ejabberd.im/faq/tcp) but have not lost my messages but just received it delay.
I am use smack-4.2 lib on my Android app.and following code used to enabled stream management in XMPPTCPConnection.
static{
XMPPTCPConnection.setUseStreamManagementDefault(true);
XMPPTCPConnection.setUseStreamManagementResumptionDefault(true);
}
Here's my ejabbered.cfg file for mod_stream_management module
{mod_stream_management, [
% default 100
% size of a buffer of unacked messages
% {buffer_max, 100}
% default 1 - server sends the ack request after each stanza
% {ack_freq, 1}
% default: 600 seconds
% {resume_timeout, 600}
]},
I have also enable following module on my config file
%% Only archives for c2c messages, good performance.
{mod_mam_odbc_user, [pm]},
{mod_mam_cache_user, [pm]},
% {mod_mam_mnesia_dirty_prefs, [pm]},
% {mod_mam_odbc_arch, [pm, no_writer]},
{mod_mam_odbc_async_pool_writer, [pm]},
{mod_mam, []}
I found little solution here smack connect to xmpp server with previous stream id but its not work on mongooseIM-2.0 server.
Thank you in advanced.
I'm assuming below that user A, when they reconnect, is not using Stream Resumption (as defined by XEP-0198: Stream Management) and merely starting a new session.
This means that on the server side there's still a dangling process waiting for Stream Resumption to happen. When user A is already reconnected to the server, the dangling process times out (which takes resume_timeout seconds) and sends the messages it had stored for delivery in the outgoing message buffer.
If you don't like this behaviour, you can do one of these:
a) (not advised) disable Stream Management and send a Message Archive Management query (that is use mod_mam) to have the most up to date conversation state each time you establish a new connection to the server
b) leave Stream Management enabled, but use Stream Resumption if only possible; that is, you always try to resume the previous session, unless you don't have the previous session ID or the server rejects the resumption request; ideally you would also use Message Archive Management
c) use Delayed Delivery aka mod_offline, but risk that in some rare cases, if you use multiple devices, the messages might be sent to a wrong device; for example, if you have a phone and a laptop, it might happen that your messages will reach the laptop, but never reach the phone
Did you try using mod_ping and configure on ejabbered.cfg file.
{mod_ping, [{send_pings, true}]},
fore more details please follow this link mod_ping
We are using GCM’s XMPP protocol to deliver push notifications to our customers, the problem we are facing is that when sending xmpp messages with high speeds, we don’t receive 'ack' or 'nack' messages from GCM anymore, These are the results of several tests we did for this matter :
500 XMPP messages - sent every 0.25 seconds:
all messages are acked
500 XMPP messages - sent every 0.1 seconds:
On average, ~4 messages remained un-acked
500 XMPP messages - sent every 0.01 seconds:
72 messages remained un-acked
500 XMPP messages - sent with no sleep time (As fast as possible)
reached the 100 unacked message limit set by GCM in less than 0.5 seconds !
The results are even worse when we go for more than 500 messages, E.g :
4000 XMPP messages - sent every 0.1 seconds:
On average, number of un-acked messages rose to about 16
4000 XMPP messages - sent every 0.01 seconds:
On average, reached the 100 unacked limit in the 800th xmpp message.
——————————————————————————————————
These results are from tests done on Google’s own cloud (Google cloud compute servers), while doing them in anyother place, would yield much worse results ( as we tested, no speed more than 1Msg/0.4S w
We are using GCM’s XMPP protocol to deliver push nould actually survive (!) the 100 unacked limit)
This is too bad for us, since there’s no optimal solution out, what should we do now?
Ignore the 100 unacked limit and continue sending, but that would mean we don’t know whether our messages are received by gcm or not.
We can resend any unacked message after several seconds, but duplicate messages (to same clients) are a result.
Wait to see if they maybe get acked in the near future, but that so far hasn’t worked. When we get to the unacked limit, pending messages are never acked (in our experience)
Limit the speed by which we send XMPP messages, but this solution greatly jeopardizes the main initiative we had to actually use XMPP !
Any help or guidance would be greatly appreciated.
I also had the same problem. I used to send ACKs for gcm's NACKs and when I stopped doing so, everything went perfectly fine. Check to see if you are sending unnecessary ACKs.
Hi anyone has some experience on scaling GCM XMPP ?
https://developer.android.com/google/gcm/ccs.html
Im reading docs there but Im not sure about this 100 pending msgs on 1 connection. I read somewhere that there is limit to 10 connections on server, is it right ? What f I will run 5 servers, each will open 10 connections, should it work well ?
Regarding 100 pending messages:
So apps can use "messages with payload" " to deliver messages of up to 4 Kb. This would be useful in a chat application, for example. To use this feature, simply omit the collapse_key parameter and messages will not be collapsed. GCM will store up to 100 messages. If you exceed that number, all messages will be discarded but you will receive a special message. If an application receives this message, it needs to sync with the server.
Regarding Server connection limit:
You can allow your server to send up to 4000 messages per second on the persistent connection. Knowing you are allowed up to 10 connections, you can possibly send many notifications fast (up to 40k notifications per second).
So you can speed up the message delivery on a device without eventually increasing the number of connections or number of servers but rather splitting your array of devices.
For faster delivery try these methods: 1. delay_while_idle - set to false 2. time_to_live - set to zero (but we have set to 30 for just in case) 3. Canonical IDs - Make sure Canonical IDs returned by GCM replace the old PushID in database 4. collapse_key - The most important factor - set it to random or TOD to avoid Google to throttle notifications.
In extreme case you can always airpush.
I have downloaded and setup the Android gcm-client and gcm-demo-server (http server) from http://code.google.com/p/gcm/ . I have managed to receive downstream messages in my Android gcm-client app. I have done numerous tests with the following characteristics:
The server used either a browser API key or a server API key.
The data connection was either 3G or WiFi
The sent message included/didn't include additional data.
The sent message had/didn't have a collapse key.
The sent message had delayWhileIdle set to false.
The sent message had timeToLive set to 0 or 5 minutes.
The server was located in two different locations within Europe.
The Android app run in two devices located in different places within Europe.
In all cases the app receives the sent messages after 25-30 sec from the moment they were sent. However, I have tested other Android applications that use GCM downstream messages and in most cases the messages arrive almost instantly (<5sec).
Is there something I can change in the client or server in order to have the messages received in the app sooner?
I also tried to use the gcm XMPP server (Java application using Smack) given in http://developer.android.com/google/gcm/ccs.html but I didn't manage to sent any messages. The response I receive from GCM Cloud Connection Server (CCS) says "Project XXXXXXXXXX not whitelisted". The most possible reason is that my registration for CCM has not been approved yet as described in Google CCS (GCM) - project not whitelisted . As I have read in various websites, the approval usually takes more than 2-3 months, so I will most possibly not be able to test the XMPP server soon.
Is it possible that you can only receive nearly instant messages by using an XMPP server? Does anybody have any experience of the delays encountered using an XMPP server?
Thanks in advance
I think that the problem is in the android gcm-client demo that are retaining the message, not in the gcm-server.
In GcmIntentService.java file of gcm-client demo, it can be seen that the function protected void onHandleIntent(Intent intent) have the following code:
[...]
// If it's a regular GCM message, do some work.
} else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
// This loop represents the service doing some work.
for (int i = 0; i < 5; i++) {
Log.i(TAG, "Working... " + (i + 1)
+ "/5 # " + SystemClock.elapsedRealtime());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
}
[...]
This code sleeps android application 5 seconds every iteration (total 25 seconds) before deliver a notification message. You can delete this code due to is an example and you can insert into else if statement some work before show notification.
I have implemented a xmpp server and I receive the notification in <5 seconds, without this working code, of course.
Hope this help and sorry for my bad English.
I was Posting Data from Android Mobile to Server over HTTP connection. I was able to POST data to server and also get acknowledgement from Server. But sometime if my server communication thread waiting for acknowledgement from server after posting data that time i loss Internet Connectivity and thread unable to receive Ack from server and goes in infinite loop. I tried setReadTimeOut(180000) method.
Can it work for me? Can it gives SocketTimeOutException if no network Available/ No connection between server and mobile
Setting a timeout will most likely work. However, I would not recommend setting it to 180000 (= 180 seconds = 3 minutes!). 30 seconds is usually more than enough. You also might want to add a setConnectTimeout
Note that there are some situations where an HttpUrlConnection doesn't always work properly:
Android versions 2.2 or earlier, better use the Apache HTTP client for these versions (see also this post)
On the emulator (see also this post)