Android 使用 XMPP 服务器和 Google 云消息(或更新的 Firebase 云消息)推送通知的聊天应用程序

Chat App for Android using a XMPP Server and Google Cloud Messaging (or the newer Firebase Cloud Messaging) for Push Notifications

我正在为 Android 开发聊天应用程序。我已经阅读了数周有关 XMPP 和 Google 云消息传递(以及 Firebase 云消息传递)的文章,但我仍然很困惑。

目前,我已经在本地 (Ejabberd) 设置了一个 XMPP 服务器,并使用 Smack 库成功地将我的 Android 应用程序连接到它。

据我了解,我需要使用 GCM 或更新的 FCM 进行推送通知,因此我已经在 Google Cloud Platform 中创建了一个项目。我的 Android 应用程序也可以使用 Smack 库连接到它(而不是直接连接到我的 XMPP 服务器)。在我的服务器中,我有一个小型 Java 应用程序,它也使用 Smack 库连接到 GCM。

到这里为止一切都很好。我最大的困惑是:如何将我的 XMPP 服务器与 GCM 一起用于推送通知? 我找到的有关服务器端实现的所有文档、示例、指南和教程都告诉我如何连接到GCM 但 none 告诉我如何将我的 XMPP 服务器与 GCM 结合使用。 我错过了什么?我的 Java 应用程序只是连接到 GCM,从 GCM 接收消息和向 GCM 发送消息,但我的 XMPP 服务器只是坐在那里什么都不做。实际上我的 Android 应用程序和服务器 Java 应用程序只使用 GCM,而不是我的 XMPP 服务器。

我希望有人能帮助我从整体上理解这一点,我显然缺少实现这一实现的一些关键要素。

您应该设置一个 Java 连接到 FCM(以前称为 GCM)的服务器。然后您可以从您的设备向 FCM 发送上游消息,FCM 然后将该上游消息发送到您的 java 服务器,然后在该 Java 服务器中您可以处理该上游消息以将下游消息发送到目标设备)。然后在设备端,您可以处理接收到的下游消息以提供推送通知。

一些有用的链接:

如何发送上游消息:
https://firebase.google.com/docs/cloud-messaging/upstream#sample-send

如何接收和处理下游消息:
https://firebase.google.com/docs/cloud-messaging/downstream#sample-receive

我如何设置示例 Java 服务器:

您需要将 Ejabberd 和 FCM 混合在一起,所有大型聊天应用程序都是这样做的。对于最基础的部分,有 3 个组件:通过 XMPP 连接到 FCM 的应用服务器、Ejabberd 和您的客户端应用程序。

  1. 当应用程序在前台时,您可以使用 Smack 库直接连接到您的 Ejabberd 服务器、发送消息、更改用户状态等。与您的 Ejabberd 的连接在此期间保持。您不要在此期间发送上行消息!
  2. 一旦用户离开您的应用,您就关闭连接。该用户现在被视为 "Away" 或 "Offline"。
  3. 从现在开始,您的应用服务器将与 FCM 通信,以向使用 Smack 库的设备发送下游消息
  4. 在客户端设备上:您处理传入的消息并显示通知。使用 Android N,用户可以直接从通知中回复。我假设在这种情况下,您将使用 FCM 将上游消息发送到您的应用程序服务器,因为在此期间,与您的 Ejabberd 服务器没有活动连接。
  5. 用户点击通知后,应用程序返回前台,您重新连接到 Ejabberd 并返回到第 1 步。

这是对架构的最基本描述,您应该拥有它来实现您想要的。

这是一个示例 java 项目,用于展示 Firebase 云消息传递 (FCM) XMPP 连接服务器。这个项目是一个非常简单的独立服务器,我作为一个更大项目的基础开发的。它是我们必须在我们的环境中实现的应用程序服务器。此服务器使用 XMPP 协议通过 FCM CCS 服务器向客户端应用程序发送数据。

https://github.com/carlosCharz/fcmxmppserver

我还在 youtube 上制作了一个视频,解释了它的作用。

https://www.youtube.com/watch?v=PA91bVq5sHw

希望您觉得它有用。

我还在 Android 中使用 Smack v.4.1.8 构建聊天应用程序,这是 Smack 的最新版本,我们的服务器使用的是 ejabberd。我没有使用 GCM 或 Firebase 等任何第三方将下游消息从用户推送到用户消息。如果我没记错的话,你打算使用 GCM 或 Firebase 将用户推送到用户消息,如果是的话就不要那样做。

为什么? 当连接建立并仍然连接时,TCP 协议会一直侦听您在 App 中注册的调用侦听器。 Smack 有一个名为 "addAsyncStanzaListener()"

的侦听器

addAsyncStanzaListener 用于监听App中的接收包。他们有

 public void processPacket(Stanza packet) 

您可以调用它,然后您将随着时间的推移收听数据包。

我正在研究如何保持 Smack 的稳定连接。大多数 Android 智能手机都有各种配置和限制。我们无法测试所有设备。 这是我保持连接稳定的提示:

  1. 使用 ForegroundService 而不是 BackgroundService,我提出这种方法是因为大多数 Android 设备对后台 运行 的应用程序有限制。当应用程序从任务管理器中滑动时,他们将终止应用程序。 (例如 Asus zenphone 有电源管理)
  2. ForegroundService 将防止应用处于空闲状态。
  3. 注册重新连接管理器
  4. 注册 Ping 失败
  5. 注册 ServerPingWithAlarmManager

就是这样。如有任何疑问,请在下方评论:)

此致 R 阿迪亚古梅

您的建议对 tcp/ip 永不掉线的连接有效。这在移动 3G/4G 网络中并非如此。所以在真实的 3G/4G 网络中,手机 client/APP 可能处于僵尸状态(断开连接)。 这就是为什么你需要 Firebase/FCM 来玩。