java 使用 XMPP 服务器和 Google Cloud Messaging(或更新的 Firebase Cloud Messaging)进行推送通知的 Android 聊天应用程序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38167622/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Chat App for Android using a XMPP Server and Google Cloud Messaging (or the newer Firebase Cloud Messaging) for Push Notifications
提问by Santiago Fermín
I'm developing a Chat App for Android. I have been reading for weeks about XMPP and Google Cloud Messaging (and Firebase Cloud Messaging) and I am still very confused.
我正在为 Android 开发一个聊天应用程序。我已经阅读了几个星期关于 XMPP 和 Google Cloud Messaging(和 Firebase Cloud Messaging)的文章,但我仍然很困惑。
Currently, I already setup an XMPP server locally (Ejabberd) and successfully connected my Android App to it using the Smack library.
目前,我已经在本地设置了一个 XMPP 服务器(Ejabberd)并使用 Smack 库成功地将我的 Android 应用程序连接到它。
To my understanding, I need to use GCM or the newer FCM for Push Notifications, so I already created a project in Google Cloud Platform. My Android App can connect to it using the Smack library too (instead of connecting to my XMPP server directly). In my server I have an small Java app that connects to GCM using the Smack library too.
据我了解,我需要使用 GCM 或更新的 FCM 来进行推送通知,所以我已经在 Google Cloud Platform 中创建了一个项目。我的 Android 应用程序也可以使用 Smack 库连接到它(而不是直接连接到我的 XMPP 服务器)。在我的服务器中,我有一个小型 Java 应用程序,它也使用 Smack 库连接到 GCM。
Everything is fine until here. My big confusion is: How can I use my XMPP server with GCM for Push Notifications?Every documentation, examples, guides, tutorials I found for server-side implementations just tell me how to connect to GCM but none tell me how to use my XMPP server in conjunction with GCM. What I'm missing? My Java app just connects to GCM, receive and send messages from and to GCM, but my XMPP server is just sitting there doing nothing. Actually my Android App and server Java App use GCM exclusively, not my XMPP server.
一切都很好,直到这里。我最大的困惑是:如何将我的 XMPP 服务器与 GCM 一起用于推送通知?我为服务器端实现找到的每个文档、示例、指南、教程都只是告诉我如何连接到 GCM,但没有告诉我如何将我的 XMPP 服务器与 GCM 结合使用。我缺少什么?我的 Java 应用程序只是连接到 GCM,从 GCM 接收和发送消息,但我的 XMPP 服务器只是坐在那里什么也不做。实际上我的 Android 应用程序和服务器 Java 应用程序专门使用 GCM,而不是我的 XMPP 服务器。
I hope someone can help me to understand this as a whole, I am obviously missing some key elements to achieve this implementation.
我希望有人可以帮助我从整体上理解这一点,我显然缺少实现此实现的一些关键要素。
采纳答案by Nimrod Dayan
You need to mix both Ejabberd and FCM together, that's how all the big chat apps do it out there. For the very basics, there are 3 components: App Server connected via XMPP to FCM, Ejabberd and your client app.
您需要将 Ejabberd 和 FCM 混合在一起,这就是所有大型聊天应用程序的做法。对于最基本的,有 3 个组件:通过 XMPP 连接到 FCM、Ejabberd 和您的客户端应用程序的应用程序服务器。
- When the app is in the foreground, you use Smack library to connect directly to your Ejabberd server, send messages, change user's presence, etc. The connection to your Ejabberd is kept during that time. You don'tsend upstream messages during this time!
- Once the user navigates away from your app, you close the connection. The user is now considered "Away" or "Offline".
- From this point and on, your App Server communicates with FCM to send downstream messagesto the device using Smack library as well.
- On the client device: You handle the incoming message and show a notification. With Android N, users can reply directly from the notification. I assume that in this case, you would use FCM to send an upstream message to your app server since during that time, there's no active connection to your Ejabberd server.
- Once the user taps on the notification, the app comes back to foreground and you re-connect to Ejabberdand back to step 1.
- 当应用程序在前台时,您使用 Smack 库直接连接到您的 Ejabberd 服务器、发送消息、更改用户的状态等。在此期间保持与您的 Ejabberd 的连接。在此期间您不要发送上游消息!
- 一旦用户离开您的应用程序,您就关闭连接。用户现在被视为“离开”或“离线”。
- 从现在开始,您的 App Server 将与 FCM 通信以使用 Smack 库向设备发送下游消息。
- 在客户端设备上:您处理传入消息并显示通知。使用 Android N,用户可以直接从通知中回复。我假设在这种情况下,您将使用 FCM 向您的应用服务器发送上游消息,因为在此期间,您的 Ejabberd 服务器没有活动连接。
- 一旦用户点击通知,应用程序就会回到前台,您重新连接到 Ejabberd并返回到步骤 1。
This is the very basic description of the architecture you should have to achieve what you want.
这是实现您想要的架构所需的非常基本的描述。
回答by Carlos Becerra Rodriguez
This is a sample java project to showcase the Firebase Cloud Messaging (FCM) XMPP Connection Server. This project is a very simple standalone server that I developed as a base of a larger project. It is an application server that we must implement in our environment. This server sends data to a client app via the FCM CCS Server using the XMPP protocol.
这是一个示例 Java 项目,用于展示 Firebase 云消息传递 (FCM) XMPP 连接服务器。这个项目是一个非常简单的独立服务器,我开发它作为一个更大项目的基础。它是我们必须在我们的环境中实现的应用服务器。该服务器使用 XMPP 协议通过 FCM CCS 服务器将数据发送到客户端应用程序。
https://github.com/carlosCharz/fcmxmppserver
https://github.com/carlosCharz/fcmxmppserver
And also I've created a video in youtube where I explain what it does.
我还在 youtube 上创建了一个视频,在那里我解释了它的作用。
https://www.youtube.com/watch?v=PA91bVq5sHw
https://www.youtube.com/watch?v=PA91bVq5sHw
Hope you find it useful.
希望你觉得它有用。
回答by Riley MacDonald
You should set up a Java server which connects to FCM (formerly GCM). Then you can from your device send an upstream message to FCM who then sends that upstream message to your java server and then within that Java server you can handle that upstream message to send a downstream message to the targeted device(s). Then on the device side you can handle those downstream messages being received to give a push notification.
您应该设置一个连接到 FCM(以前称为 GCM)的 Java 服务器。然后,您可以从您的设备向 FCM 发送上游消息,FCM 然后将该上游消息发送到您的 Java 服务器,然后在该 Java 服务器中,您可以处理该上游消息以向目标设备发送下游消息。然后在设备端,您可以处理接收到的那些下游消息以提供推送通知。
A few useful links:
How to send an upstream message:
https://firebase.google.com/docs/cloud-messaging/upstream#sample-send
How to receive and handle downstream messages:
https://firebase.google.com/docs/cloud-messaging/downstream#sample-receive
How I set up an example Java server:
https://stackoverflow.com/a/38170310/4433653
一些有用的链接:
如何发送上游消息:
https:
//firebase.google.com/docs/cloud-messaging/upstream#sample-send
如何接收和处理下游消息:
https:
//firebase.google.com /docs/cloud-messaging/downstream#sample-receive
我如何设置示例 Java 服务器:https:
//stackoverflow.com/a/38170310/4433653
回答by raditya gumay
I am also building chat application in Android using Smack v.4.1.8 which latest version of Smack, and our server is using ejabberd. I am not use any third party like GCM or Firebase to push downstream message from user to user message. If i am not wrong you going to use GCM or Firebase to push user to user message, if yes just dont do that.
我还在 Android 中使用 Smack v.4.1.8 构建聊天应用程序,这是最新版本的 Smack,我们的服务器正在使用 ejabberd。我不使用任何第三方(如 GCM 或 Firebase)将下游消息从用户推送到用户消息。如果我没有错,您将使用 GCM 或 Firebase 将用户推送到用户消息,如果是,请不要这样做。
Why? TCP protocol is keep listening a invoke listener which you registered in App when the connecting establish and still connected. Smack has a listener which called "addAsyncStanzaListener()"
为什么?TCP 协议会在连接建立并仍然连接时继续侦听您在 App 中注册的调用侦听器。Smack 有一个名为“addAsyncStanzaListener()”的监听器
addAsyncStanzaListener is used to listen a receive packet in App. They have
addAsyncStanzaListener 用于在 App 中监听接收数据包。他们有
public void processPacket(Stanza packet)
You can invoke that, and you will listen the packet over the time.
您可以调用它,随着时间的推移,您将收听数据包。
I do a research about keeping stable connection of Smack. Most of Android Smartphone have each configuration, and restriction. We cannot test all of devices. Here my tips to keep connection stable:
我做了一个关于保持 Smack 稳定连接的研究。大多数Android智能手机都有各自的配置和限制。我们无法测试所有设备。这是我保持连接稳定的提示:
- Use ForegroundService instead BackgroundService, i propose this approach because most of Android Device have restriction to an app which run in background. They will kill app when the app swipe from task manager. (e.g Asus zenphone have power management)
- ForegroundService will prevent app from being idle.
- Register ReconnectingManager
- Register Pingfailed
- Register ServerPingWithAlarmManager
- 使用 ForegroundService 代替 BackgroundService,我提出这种方法是因为大多数 Android 设备都限制在后台运行的应用程序。当应用程序从任务管理器滑动时,他们将终止应用程序。(例如华硕zenphone有电源管理)
- ForegroundService 将防止应用程序空闲。
- 注册重连管理器
- 注册 Ping 失败
- 注册 ServerPingWithAlarmManager
And that's it. Any enquiries, just comment below :)
就是这样。有任何疑问,请在下方评论:)
Best Regard R Aditya Gumay
最好的问候 R Aditya Gumay
回答by TC Juan
Your suggestion is valid for a connection with tcp/ip never drop. which is not the case in Mobile 3G/4G network. So in real 3G/4G network, the mobile client/APP might be in zombie state(disconnected). That is why you need Firebase/FCM to come to play.
您的建议适用于与 tcp/ip never drop 的连接。这在移动 3G/4G 网络中并非如此。所以在真实的 3G/4G 网络中,移动客户端/APP 可能处于僵尸状态(断开连接)。这就是为什么您需要 Firebase/FCM 来发挥作用。