当 Android 平板电脑进入待机状态时,队列将在 6 分钟后被删除

Queues are deleted after 6 minutes, when Android tablet goes in standby

大约 6 分钟后,当设备处于睡眠模式时,客户端(akà 浏览器)没有从订阅的队列中收到任何新更新。如果我查看 RabbitMQ Management,相关队列就会消失(例如命名为 stomp-subscription-MBSsZ9XB0XCScXbSc3bCcg)。唤醒设备后,将创建新队列,并且消息传递仅适用于新创建的消息。旧的从未到达设备。

这是我的设置:

这是消息从后端发送到前端的方式:

AMQPMessage<CustomNotificationMessage> msg = new AMQPMessage<CustomNotificationMessage>(
    1, SOME_ROUTING_KEY, mand, trigger, new CustomNotificationMessage() );
rabbitTemplate.setRoutingKey(SOME_ROUTING_KEY);
rabbitTemplate.convertAndSend(msg);

RabbitMqConfig.java:

@Bean
public RabbitTemplate rabbitTemplate() {
    CachingConnectionFactory connectionFactoryFrontend = new CachingConnectionFactory("some.url.com");
    connectionFactoryFrontend.setUsername("usr");
    connectionFactoryFrontend.setPassword("pass");
    connectionFactoryFrontend.setVirtualHost("frontend");

    RabbitTemplate template = new RabbitTemplate(connectionFactoryFrontend);      
    template.setMessageConverter(jsonMessageConverter());
    template.setChannelTransacted(true);
    template.setExchange("client-notification");
    return template;
}

我现在的想法是对前端队列使用 TTL。但是我该怎么做,我根本没有创建队列?

另一方面,我在 RabbitTemplate 中看到 setReceiveTimeout()setReplyTimeout()setDefaultReceiveQueue() 等方法,但我不知道这是否正确。它更多的是客户的事情吗?客户端的 Subscription 如下所示:

this.someSubscription = this.rxStompService.watch('/exchange/client-notification/SOME_ROUTING_KEY')
    .subscribe(async (message: Message) => {
    // do something with message
}

这是根据my-stomp-config.ts:

export const MyStompConfig: InjectableRxStompConfig = {
  // Which server?
  brokerURL: `${environment.BrokerURL}`,

  // Headers
  // Typical keys: login, passcode, host
  connectHeaders: {
    login: 'usr',
    passcode: 'pass',
    host: 'frontend'
  },

  // How often to heartbeat?
  // Interval in milliseconds, set to 0 to disable
  heartbeatIncoming: 0, // Typical value 0 - disabled
  heartbeatOutgoing: 20000, // Typical value 20000 - every 20 seconds

  // Wait in milliseconds before attempting auto reconnect
  // Set to 0 to disable
  // Typical value 500 (500 milli seconds)
  reconnectDelay: 500,

  // Will log diagnostics on console
  // It can be quite verbose, not recommended in production
  // Skip this key to stop logging to console
  debug: (msg: string): void => {
    //console.log(new Date(), msg);
  }
};

documentation里看到一个connectionTimeout参数,不过默认值应该没问题。

Default 0, which implies wait for ever.

关于电源管理的一些话:我将应用程序排除在节能之外,但这并没有改变什么。默认浏览器也会发生这种情况。

如何让前端队列的存活时间超过六分钟?

主要问题是如果操作系统正在削减资源(WiFi、CPU、...),您将无能为力。如果您唤醒设备,队列将再次创建,但所有旧消息(当设备处于休眠状态时)都将丢失。

因此解决方法是在设备唤醒时重新加载数据。因为这是特定于应用程序的代码示例,所以用处不大。我在浏览器控件中订阅时使用 Xamarin.Forms OnResume()MessagingCenter。从那里我执行 Javascript 代码 postMessage() 和自定义消息。

Web 应用程序本身具有这些消息的侦听器并相应地重新加载数据。