繁体   English   中英

Smack 4.1重新连接问题

[英]Smack 4.1 Re-connection issue

我正在开发一个聊天应用程序

  1. 我有一个持续运行的后台服务。
  2. 应用程序运行顺利,我能够毫无问题地接收和发送消息。
  3. 我正在使用默认的Smack 4.1重新连接管理器,它会在连接丢失后立即连接(几乎90%的时间)。

但有时,当连接丢失时,Smack重新连接管理器停止工作。

我无法找出造成这个问题的原因。

当我检查手机后,经过12到14小时的延迟,我可以看到Android服务仍在运行,但XMPP重新连接已停止工作。 然后我必须强制停止应用程序,然后重新启动服务并让它再次连接到XMPP服务器。

我的假设是当“电话网络从Wifi到数据或数据到Wifi”切换时。 与此同时,Smack 4.1重新连接管理器停止工作。 虽然,我不确定。

我有问题

  1. PingManager有什么用? PingManager在这种情况下可以提供帮助吗?
  2. 什么是StreamManagement? 我该如何启用它? 这种情况有用吗?

任何其他解决方案来解决这个问题? 我在考虑以下解决方案:

  1. 要使用GCM以及XMPP,所以当XMPP无法重新连接时,我可以获得PUSH并在PUSH的基础上再次连接。
  2. 使用警报服务。 问题:由于连接丢失而在队列中的消息将取决于下一个警报计划)
  3. 每次用户返回应用程序时连接XMPP。 问题:因连接丢失而在队列中的消息将取决于用户返回应用程序)

有点晚,但也许有助于其他人。 我不是XMPP专家,但我遇到了一个名为“XMPP和Android”的Ignite Realtime演示文稿,它指出了这个问题以及如何处理这个问题。 第1页

第2页

它提供服务器ping与Alarm Manager理想情况下,间隔30分钟。

我还发现了另一篇与此问题相关的帖子,并提供了3个选项。 值得一看。 https://ramzandroidarchive.wordpress.com/2016/03/14/handling-connection-break-issue-in-smack-4-1/

这有点旧问题,但我个人在过去使用Smack维持持久连接时遇到了困难,并且必须根据多种资源找出答案。 我将尝试在这个答案中解决我的发现。

注意 - 不要使用AbstractXMPPConnection isConnected()方法来确定连接是否处于活动状态。 这仅仅是对象的内部状态。 它没有真正的方法来了解连接是否实际上是活动的。
唯一可以确定的方法是通过服务器或客户端进行ping操作。

持久连接路由 - 不推荐

首先要理解的是 - 如果你确实想要与服务器建立持久连接(我一直都是这条路线并且不推荐它 - 下面有更多关于它的信息),你必须手动完成。
在服务器端 - 确保在一段合理的时间后断开空闲的客户端(太长时间并且您将丢失消息,因为连接将被终止但服务器仍将其视为活动状态。太短并且您将重复如果您的用户网络连接不良,我们会断开连接。我个人用户30秒。我想30到60秒之间的任何事情都可以。) 这将允许您在客户端检测何时丢失与服务器的连接。
要做的第二件事是实现ConnectionListener Smack接口。 它包含对各种连接事件的回调,例如connectionClosedOnError ,它允许您恢复与服务器的连接。
然后你应该听网络连接事件 - 如果用户改变了网络,你应该断开连接并重新连接。
这是有争议的,但我个人遇到了以这种方式保持连接的问题,依赖于服务器ping和回调。 如果你也有 - 你应该从客户端ping服务器以确定。
Smack准确地具有ServerPingWithAlarmManager类 - 它每隔30分钟对服务器进行一次ping操作。 唉,对我来说这没用,因为一些原始设备制造商(小米我看着你)在他们的自定义Android皮肤中限制了后台任务。 对我有用的方法是使用自定义PingManager ping服务器。 使用PingManager.getInstanceFor(connection)获取它,并使用PingManager.getInstanceFor(connection)其安排为每隔X分钟(7分钟为我工作) AlarmManager
对于此ping管理器,您应该注册一个PingFailedListener ,它将在其pingFailed()方法上重新连接。
这一切听起来都不好? 这是最糟糕的部分 - 整个事情在api> = 23时分开。这一切都很好,直到Doze和App Standby发挥作用。 这就是为什么如果你去坚持连接路线 - 你必须要求可怕的ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS权限,允许你的应用程序绕过Doze和App Standby。
恭喜! 假设谷歌没有禁止你的应用程序从Play商店请求白名单电池优化权限 - 你现在有一个可靠和持久的xm​​pp与你的服务器内的服务器连接, 即使用户什么都不做也不会疯狂地耗尽电池它很长一段时间 正如我之前所说,这不是一个理想的解决方案。

更好的解决方案 - FCM高优先级消息

在了解了与服务器保持连接的问题之后 - 这是我推荐使用的方法。
不要试图对抗网络连接和电池优化,这些优化对每个Android版本都有更严格的限制。
将FCM消息集成到您的服务器中将允许您的用户即使在设备处于打盹模式时也能实时接收消息。
这是我用时下的方法,它工作得很好, 很多具有低得多的电池消耗的好处。
我没有ping服务器,服务器没有ping我的应用程序。 当设备更改网络或由于错误导致连接关闭时 - 我只是断开连接。
连接时,消息由Message类型StanzaListener接收。
断开连接时, FirebaseMessagingService()实现会收到消息。
无需坚持连接。 无需与系统作斗争。 没有巨大的电池排水。

希望这个答案可以帮助将来的某些人并节省一些时间,因为我花了很多时间,精力和反复试验来找到我满意的解决方案。

暂无
暂无

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

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