当前位置: 首页 > 面试题库 >

Google Cloud Messaging-即时收到的消息或延迟很长时间的消息

卫振
2023-03-14
问题内容

我在大学的最后一个项目中正在使用Google云消息传递。一切正常,但是我在使用GCM时遇到了一些麻烦。通常,消息要么立即发送,要么延迟很大。

我已经读过了,在这种情况下我真的不认为它适用:

GCM通常会在邮件发送后立即发送。但是,这并不总是可能的。例如,设备可能已关闭,处于脱机状态或不可用。在其他情况下,发件人本身可能会使用delay_while_idle标志要求在设备变为活动状态之前不传递消息。最后,GCM可能会故意延迟消息,以防止应用程序消耗过多的资源并对电池寿命产生负面影响。

在我的项目中,每分钟最多只能讨论来自服务器的5到6条消息。如果可以肯定地将GCM用于聊天应用程序,则它们不能阻止以此速率发送/接收的消息吗?如果我的项目仅在50%的时间里有效,它将变得很烦人并且会变得非常糟糕。

这是服务器发送的消息的我的代码

@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();
            }
        }
}

而我的Android onMessage方法

@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();

        }
    });
    */
}

我希望有人也遇到过类似的问题,我只是想确认问题是我在做什么,还是问题不在我手中。

tl; dr GCM消息可以立即到达,也可以在大约10分钟后到达(延迟通常是一致的)。


问题答案:

客户端电话上的GCM框架部分使用端口5228上的 TCP连接
。此连接用于推送通知,但由于每个tcp连接,它可能会与某些应用严格策略以杀死不活动tcp连接的路由器/运营商进行超时( tcp空闲超时 )。

例如,大多数wifi路由器会在5分钟后杀死无效的连接,例如我的。

GCM框架使用 保持活动
机制在wifi上每15分钟发送一次心跳网络数据包,在3G上每28分钟发送一次心跳网络数据包。此保持活动并非始终对所有用户可靠。

我在这里向Google打开了这个问题:https :
//productforums.google.com/forum/#!category-
topic/ nexus/
connecting- to-networks-and-
devices/ fslYqYrULto 他们同意当前存在问题。

编辑(2014/01/08)
:当前,Google已将心跳间隔更新为8分钟,以连接wifi和移动设备。可能会影响所有android设备2.2+的远程更改,这是避免tcp推送连接超时的一个很好的改进。不过,如果wifi路由器在5分钟后杀死了无效的连接,则推送通知将延迟3(8-5)分钟(如果您没有其他使连接保持有效的通知)

编辑(2016/03/06)
:现在,谷歌似乎正在测试我2年前的反馈,以具有一种动态机制来根据网络确定正确的心跳间隔。就我所知,目前似乎是分阶段推出,仅适用于wifi。因此,基于wifi的SSID,算法会通过逐步优化来确定特定wifi的正确心跳间隔。听起来很好!这是一项远程更改,会影响所有具有Google
Play服务的Android手机。



 类似资料:
  • 1.场景描述:设备向Netty服务器发送数据(大约##20ms间隔##),Netty服务器向客户端转发消息##立即##(IOS或Android)。2.关联业务代码CTX.WriteAndFlush(msg) 3.发出网络服务器可以及时接收设备数据,网络服务器也可以及时将数据写入套接字缓冲区。但Netty客户端收到消息时延!!!(如5s时延) 4.服务器带宽配置入站100M/bps位/秒。出站5M/

  • 我有一个Python进程(或者更确切地说,在一个使用者组中并行运行的一组进程),它根据来自某个主题的Kafka消息输入来处理数据。通常每条消息的处理都很快,但有时,取决于消息的内容,可能需要很长时间(几分钟)。在这种情况下,Kafka broker断开客户端与组的连接,并启动重新平衡。我可以将设置为一个非常大的值,但它可能会超过10分钟,这意味着如果客户机死亡,集群在10分钟内无法正确地重新平衡。

  • 在测试应用程序中,我使用以下命令实现了用于发送通知消息的FCM https://github.com/firebase/quickstart-android/tree/master/messaging 为了进行测试,我使用通知下的“新消息”从Firebase控制台发送了消息(晚上8:42)。 但在我的模拟器中,我在晚上9:06收到了消息 请让我知道是否有什么可以减少延误。 谢谢你。

  • 如何使用Apache Kafka生成/使用延迟消息?标准的Kafka(和Java的kafka-client)功能似乎没有这个特性。我知道我自己可以用标准的等待/通知机制来实现它,但是它看起来不是很可靠,所以任何建议和好的实践都很感谢。 找到相关问题,但没有帮助。正如我所看到的:Kafka基于从文件系统的顺序读取,并且只能用于直接读取主题,保持消息的顺序。我说的对吗?

  • 主要内容:1 load加载延迟消息数据,1.1 parseDelayLevel解析延迟等级,2 start启动调度消息服务,3 DeliverDelayedMessageTimerTask投递延迟消息任务,3.1 executeOnTimeup执行延迟消息投递,3.2 scheduleNextTimerTask下一个调度任务,3.3 correctDeliverTimestamp校验投递时间,3.4 messageTimeup恢复正常消息,,基于RocketMQ release-4.9.3,深入

  • 使用启用会话(消息排序)的Azure ServiceBus队列,我的会话需要持续几分钟到几个小时。 为此,我将QueueClient配置如下: 并按如下方式开始接收消息: 在几次(1到6次之间)成功(几乎是瞬时的)消息接收回调之后——无论是对于新会话还是现有会话,接收处理程序都会停止触发。使用,我可以看到位于servicebus队列上的消息。有趣的是,它们都有一个DeliveryCount=1。过