以安全的方式重用 asmack 连接或在断开连接(包括断开的 TCP 连接)的情况下重新创建它?
Posted
技术标签:
【中文标题】以安全的方式重用 asmack 连接或在断开连接(包括断开的 TCP 连接)的情况下重新创建它?【英文标题】:Reuse asmack connection or recreate it in case of disconnect ( including broken TCP connections) in a safe way? 【发布时间】:2014-01-22 21:55:22 【问题描述】:我正在编写一个聊天应用程序,并且我正在使用 asmack 客户端库(感谢 Flow 对其进行维护 :))。问题是我不知道如何处理断开连接(正常情况,由连接侦听器通知或损坏的 TCP 引起的)
假设我在线程 A 上创建连接,即我在同一个线程上调用 connect & login。
如果由于某种原因我会断开连接,那么下一次,我应该:
重用声明为 volatile 的相同 XMPPConnection 引用,并在另一个线程上调用 connect? (因为android不允许我在主线程上调用IO?)。我不太喜欢这个想法,因为来自 XMPPConnection 的大多数变量都不是易失性的,因此从多个线程(一次一个,因此每次断开连接后我记得在新线程上连接)在同一个 XMPPConnection 上调用 connect 可能会有问题关于线程安全。
重新创建 XMPPConnection 并清理旧的?这也是一个问题,因为在转换到第二个连接时,您可能会丢失一些消息。我正在考虑使用队列来保存我的消息并在连接可用时立即写入它们。
我知道 XMPP 提供 ping 来检测服务器是否仍然存在,但如果您在 1 分钟内执行 ping,但连接断开(您从与手机,那么Android不会通知你连接丢失,你仍然可以在socket上发送消息一段时间),如何实现消息发送的完整性?
我正在考虑同步发送一些消息(ping),例如 getRoster 是在 XMPPConnection 中实现的。这样,如果我在超时后没有收到消息(smack 中的默认值为 5 秒),那么我将断开与 XMPP 的连接,假设我的连接已断开。你认为依靠超时是个好主意,否则我会搞砸移动数据连接?
我要制作的应用程序具有 WhatsApp 的风格,因此它应该可以离线工作并在重新登录时重新发送消息。如果您对此有一些建议,请分享。
非常感谢,
【问题讨论】:
你解决了这个问题吗?我面对的是同一个 您好,由于我想创建一个非常稳定的聊天应用程序,我打算编写自己的库。 Smack 并不意味着是线程安全的。认为你有一个 XMPPConnection。您在线程 1 上调用连接,然后由于某种原因断开连接(互联网关闭等)。如果您将其放入正在运行的服务中,那么当您再次在另一个线程 t2 上调用 connect 时,它看起来并不安全。如果你想创建/重新创建连接,你必须有某种队列来放置你在这两者之间的转换期间可能发送的数据包。如果你对 SMACK 有任何疑问,请问我:) 让我们继续您的第 1 点,即我们应该重用现有的 xmppConnection (mXmppCon.connect()) 还是应该清理连接并重新创建 xmppConnection。应该有什么好方法? 我想重新创作。请参阅 code.google.com/p/gtalksms/source/checkout 了解他们的所作所为 【参考方案1】:如果您想在第一次建立连接后一直保持连接,那么我认为您可以尝试在Service
android 类中保持连接。
我要制作的应用程序具有 WhatsApp 的风格,所以它应该可以工作 离线并在重新登录时重新发送消息
您需要制作一个广播接收器来监控您的数据连接何时关闭和打开。根据该事件,您需要再次重新建立 xmpp 连接(换句话说,再次启动该服务)
此外,这很简短,但在您的情况下还需要管理更多内容。我建议使用我最喜欢的开源应用程序之一GTalkSMS,它可以帮助您了解如何处理 xmpp 连接。
【讨论】:
以上是关于以安全的方式重用 asmack 连接或在断开连接(包括断开的 TCP 连接)的情况下重新创建它?的主要内容,如果未能解决你的问题,请参考以下文章
远程处理异常:对象“xxx.rem”已断开连接或在服务器上不存在
EF 代码第一次迁移报错“对象已断开连接或在服务器上不存在”
Azure SQL 数据库 -> 添加索引 -> 对象“/.rem”已断开连接或在服务器上不存在
客户端断开连接后在 .NET 4 中重用 NamedPipeServerStream 时 BeginWaitForConnection 引发的异常