谷歌云消息 - 消息或者即时或长时间延误收到消息、长时间、谷歌云

2023-09-12 10:03:55 作者:稳场浪客

我使用谷歌云消息在我最后一年的项目上大学。一切工作不错,但我一直有一个有点麻烦与GCM。 pretty的规律,消息要么传递几乎瞬间,或大的延迟。

I am using Google cloud messaging in my final year project for college. Everything works okay but I have been having a bit of trouble with GCM. Pretty regularly, messages are either delivered virtually instantly, or with a large delay.

我看过这个,我真的不认为它适用于这种情况:

I have read this and I really don't think it applies in this case:

GCM通常会立即将消息发送之后。   然而,这可能不总是可能的。例如,该设备   可以关闭,离线,或以其他方式不可用。其他   情况下,发送者本身可能要求消息不能传递   直到设备变得活跃,通过使用delay_while_idle标志。   最后,GCM可能故意拖延消息,prevent的   过量消耗资源和产生负面的应用   影响电池寿命。

GCM will usually deliver messages immediately after they are sent. However, this might not always be possible. For example, the device could be turned off, offline, or otherwise unavailable. In other cases, the sender itself might request that messages not be delivered until the device becomes active by using the delay_while_idle flag. Finally, GCM might intentionally delay messages to prevent an application from consuming excessive resources and negatively impacting battery life.

在我的项目都在谈论从服务器在5或6的消息一分钟。如果GCM可用于聊天应用程序肯定他们无法阻止的发送/以这样的速率接收的消息?它已成为pretty的烦人,将pretty的厉害,如果我的项目只适用的50%的时间......

In my project were talking about at most 5 or 6 messages from the server a minute. If GCM can be used for a chat application surely they couldn't block messages which are sent / received at this rate? It has become pretty annoying and will pretty badly if my project only works 50% of the time...

下面是我的code服务器发送消息:

Here is my code for the message the server sends:

@Override
public void run() {

    Message.Builder messageBuilder = new Message.Builder().delayWhileIdle(false);
    Gson gson = new Gson();
    messageBuilder.addData("profile", gson.toJson(profile));
    databaseConnection.notifyDevices(messageBuilder.build());

}

public void notifyDevices(Message message) {

        Sender sender = new Sender(xxx);

        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        nameValuePairs.add(new BasicNameValuePair("message", message.toString()));

        //LOG
        System.out.println("Notifying devices with the following message \n \"" +message+ "\"");

        List<String> deviceIDsList = new ArrayList<String>();
        String [] deviceIDArray;

        //Get devices to notify
        List<JSONDeviceProfile> deviceList = getDevicesToNotify();

        for(JSONDeviceProfile device : deviceList) {
            deviceIDsList.add(device.getDeviceId());

            try {
                sender.send(message, device.getDeviceId(), 5);
            } catch (IOException e) {
                System.out.println("Error sending GCM message!");
                e.printStackTrace();
            }
        }
}

和我的Andr​​oid onMessage方法:

And my Android onMessage method:

@Override
protected void onMessage(Context arg0, Intent intent) {

    String message = intent.getStringExtra("profile");

    Log.d(TAG + "Received Message: ", "Received Message: " + message.toString());

    //CALL NEW INTENT WITH PROFILE DETAILS
    Intent displayProfileIntent = new Intent(arg0, DisplayProfile.class);
    displayProfileIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    displayProfileIntent.putExtra("message", message); 
    startActivity(displayProfileIntent);

    /*
    //generateNotification(arg0, username);

    handler.post(new Runnable() {
        @Override
        public void run() {
            //Toast.makeText(getApplicationContext(), username, Toast.LENGTH_SHORT).show();

        }
    });
    */
}

我希望有人有过类似的问题,我只是想确认这个问题是我在做,或者如果它超出了我的手。

I am hoping somebody has had a similar issue, I just want to confirm that the problem is something I am doing or if it is out of my hands.

TL;博士 GCM消息或者即时或约10分钟后(延迟通常是一致的)

tl;dr GCM messages either arrive instantly or about 10 minutes later (the delay is usually consistent).

推荐答案

在客户端手机的GCM框架的一部分使用用于推送通知的端口5228.此连接其上的 TCP连接,但因为每个TCP连接,它可以继续暂停时以一些路由器/运营商适用严格的政策杀不活动的TCP连接( TCP空闲超时)。

The GCM framework part on the client phone use a TCP connection on the port 5228. This connection its used for push notifications, but as every tcp connection it can go on timeout with some routers/carriers that apply strict policies to kill inactive tcp connections (tcp idle timeout).

大多数无线路由器杀死5分钟,例如后活动的连接,像我这样的。

Most wifi routers kills inactive connections after 5 minutes for example, like mine.

在GCM框架使用的保持有效的机制来发送一个心跳的网络数据包的wifi每15分钟,每28分钟就3G。这种保活并不总是可靠的所有用户。

The GCM framework use a keep-alive mechanism to send an heartbeat network packet every 15 minutes on wifi and every 28 minutes on 3G. This keep-alive is not always reliable for all users.

我打开的问题在这里谷歌: https://productforums.google.com/forum/#!category-topic/nexus/connecting-to-networks-and-devices/fslYqYrULto 他们同意但目前的问题。

I opened the issue to google here: https://productforums.google.com/forum/#!category-topic/nexus/connecting-to-networks-and-devices/fslYqYrULto They agree there is currently an issue.

修改(2014年1月8日):目前谷歌更新了心跳间隔8分钟,WiFi和移动连接。 Tha'ts远程变化而影响的所有Android设备2.2 + 这是一个很好的改良效果,避免TCP推送连接超时。不过,如果无线路由器杀死活动连接5分钟后,你将不得不在推送通知3(8-5)分钟的延迟(如果你有这样永葆连接不是其他通知)

EDIT (2014/01/08): currently Google updated the heartbeat intervals to 8 minutes for wifi and mobile connections. Tha'ts a remote change which impact all android devices 2.2+ This is a good improvment to avoid the tcp push connection timeout. Still, if a wifi router kill inactive connections after 5 minutes, you will have a 3 (8-5) minutes delay in push notifications (if you hadn't other notifications that keep alive the connection)