简体   繁体   English

Android / Smack:在睡眠模式下保持XMPP连接处于活动状态

[英]Android/Smack: Keep XMPP connection alive in sleep mode

I have an Android application that has a chat client as one of its features. 我有一个Android应用程序,它有一个聊天客户端作为其功能之一。 The chat client uses XMPP based on the Smack library for Android and running Openfire as XMPP server in the background. 聊天客户端使用基于Android的Smack库的XMPP,并在后台运行Openfire作为XMPP服务器。 The connection is established using BOSH The whole XMPP connection handling is implemented as a service to run and listen in the background for incoming messages even if not activity of the app is in the foreground. 使用BOSH建立连接整个XMPP连接处理实现为一种服务,即使应用程序的活动不在前台,也可以在后台运行和监听传入消息。 So far, everything works perfectly fine. 到目前为止,一切都很好。

The only problem seems to be the sleep mode. 唯一的问题似乎是睡眠模式。 In the emulator (when set to "Stay Awake") or with the phone in use, the XMPP connections is holding and the app can send and receive messages. 在模拟器中(设置为“保持唤醒”时)或使用手机时,XMPP连接正在保持,应用程序可以发送和接收消息。 However, once the phone goes into sleep mode, the XMPP connection breaks down -- I can see it in the Admin Console of the Openfire server that the user is offline. 但是,一旦手机进入睡眠模式,XMPP连接就会中断 - 我可以在Openfire服务器的管理控制台中看到用户离线。 Intuitively, I want to receive messages all the time like, eg, WhatsApp. 直观地说,我想一直接收消息,例如WhatsApp。

Of course, I've searched online including Stackoverflow, but I couldn't get a definitive answer. 当然,我在网上搜索过Stackoverflow,但我无法得到明确的答案。 Often the use case seems to be that a task has to be performed periodically, say, once every hour. 用例通常似乎是必须定期执行任务,例如每小时一次。 But this doesn't seem to fir in case of a chat client. 但是,如果是聊天客户端,这似乎并不强烈。 Since I assume this is a common use case -- after all, there a so many chat apps or apps with chat features out there -- these are my question: 因为我认为这是一个常见的用例 - 毕竟,有很多聊天应用程序或带有聊天功能的应用程序 - 这些是我的问题:

  • How to I have to change / extend the app that I can receive chat message while the phone is sleeping? 如何在手机休眠时更改/扩展我可以收到聊天消息的应用程序?

  • I've stumbled upon WakeLock . 我偶然发现了WakeLock Is this the way to go or are these not suitable for my use case? 这是要走的路还是这些不适合我的用例?

  • Since Lollipop, there's also the JobScheduler API which itself uses WakeLock . 从Lollipop开始,还有JobScheduler API本身使用WakeLock Any better? 好点?

  • How does, for example, WhatsApp handles this case? 例如,WhatsApp如何处理这种情况?

On a side note: I have problems with the sleep mode using the emulator for debugging. 另请注意:我使用模拟器进行调试时出现睡眠模式问题。 When I switch off "Stay Awake" in the emulator, the screen goes black after 1+ min and the XMPP connection breaks. 当我在模拟器中关闭“保持唤醒”时,屏幕在1+分钟后变黑并且XMPP连接中断。 But I somehow have no idea how to wake up / switch the emulator back on once it went black. 但我不知道如何在模拟器变黑后重新唤醒/切换模拟器。 Android Studio actually tells me at some point that the device or something is gone, and I have to restart the emulator again. Android Studio实际上告诉我,设备或其他东西已经消失,我必须重新启动模拟器。

The exact way to resolve this issue is by using push notification. 解决此问题的确切方法是使用推送通知。

It is the natural behavior of XMPP connection to get disconnected after the specified idle interval ie when the device goes to sleep. 在指定的空闲间隔(即设备进入休眠状态)后,XMPP连接的自然行为是断开的。

Coming to the case of WhatsApp, it also uses the same XMPP and maintains a server which acts as a wrapper class on the messages exchanged. 在WhatsApp的情况下,它也使用相同的XMPP并维护一个服务器,它充当交换消息的包装类。 This server checks the message status whether it is delivered or not. 此服务器检查消息状态是否已传递。 If not delivered, it sends a push notification, now at the device end in the push service when a message is received, it checks if the connection is active and is authenticated or not. 如果未交付,它会在收到消息时发送推送通知,现在在推送服务的设备端,它会检查连接是否处于活动状态并且是否已通过身份验证。

If not authenticated, it re-establishes the connection. 如果未经过身份验证,则会重新建立连接。 In this way, the most chat apps manage this timeout exception. 这样,大多数聊天应用程序都会管理此超时异常。

Hope this helps :) 希望这可以帮助 :)

You don't need push notifications, you don't need WakeLock s. 您不需要推送通知,您不需要WakeLock Instead simply 相反

  • Whitelist your app from doze mode 从打盹模式将您的应用列入白名单
  • Use a sticky ( START_STICKY ) background service 使用粘性( START_STICKY )后台服务
  • Use Smack's ServerPingWithAlarmManager 使用Smack的ServerPingWithAlarmManager
  • Act on CONNECTIVY_CHANGED intents send by Android, and use XMPPTCPConnection 's instantShutdown() in that case. 对Android发送的CONNECTIVY_CHANGED意图采取行动,并在这种情况下使用XMPPTCPConnectioninstantShutdown()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM