android - 在 Android 客户端上接收来自 ejabberd XMPP 服务器的消息
问题描述
我正在尝试使用 ejabberd XMPP 服务器(19.02)、Smack 库(4.2.4)和使用 Android Studio 的 Android SDK 25 创建一个 Android 聊天客户端。
我遵循了此处找到的示例应用程序:https ://www.blikoontech.com/tutorials/android-smack-xmpp-introductionbuilding-a-simple-client
一切运行良好,我可以在运行该示例应用程序的两个不同 Android 设备之间发送消息。
在 ejabberd 中,可以选择使用名为 ejabberdctl 或 ejabberd REST API 的 CLI 工具直接从服务器向客户端发送消息。当我以这种方式发送消息时,Android 客户端不会收到这些消息。我尝试与 Conversations 和 Gajim 等其他客户合作,他们都可以收到它。我很确定使用这些方法发送的消息会到达,因为它们在发送到离线客户端时是作为离线消息(在 ejabberd 网络管理员上)接收的。
这是用于接收传入消息的 Android (java) 代码部分(来自该示例应用程序的 roosterconnection.java)。如果我缺少任何东西,请建议我。非常感谢。
ChatManager.getInstanceFor(mConnection).addIncomingListener(new IncomingChatMessageListener() {
@Override
public void newIncomingMessage(EntityBareJid messageFrom, Message message, Chat chat) {
///ADDED
Log.d(TAG,"message.getBody() :"+message.getBody());
Log.d(TAG,"message.getFrom() :"+message.getFrom());
String from = message.getFrom().toString();
String contactJid="";
if ( from.contains("/"))
{
contactJid = from.split("/")[0];
Log.d(TAG,"The real jid is :" +contactJid);
Log.d(TAG,"The message is from :" +from);
}else
{
contactJid=from;
}
//Bundle up the intent and send the broadcast.
Intent intent = new Intent(RoosterConnectionService.NEW_MESSAGE);
intent.setPackage(mApplicationContext.getPackageName());
intent.putExtra(RoosterConnectionService.BUNDLE_FROM_JID,contactJid);
intent.putExtra(RoosterConnectionService.BUNDLE_MESSAGE_BODY,message.getBody());
mApplicationContext.sendBroadcast(intent);
Log.d(TAG,"Received message from :"+contactJid+" broadcast sent.");
///ADDED
}
});
解决方案
这是一个可能的解释,基于我对桌面客户端 Tkabber 的实验:
我使用 Tkabber 客户端、帐户user1@localhost、资源tka1、优先级-3登录到 ejabberd 。这个实验中的负优先级很重要。
然后我执行命令发送到完整的 JID,包括正确的资源:
ejabberdctl send_stanza aaa@localhost user1@localhost/tka1 "<message>..."
客户端正确接收节。
现在我发送到裸 JID(不提供资源),另一个设置另一个资源:
ejabberdctl send_stanza aaa@localhost user1@localhost "<message>..."
ejabberdctl send_stanza aaa@localhost user1@localhost/sdsd "<message>..."
- 在这些情况下,客户端都不会收到它们,因为资源不匹配,并且它的优先级为负。我可以看到那些离线存储在数据库中的消息。
在您的客户中,也许您必须添加另一个呼叫以设置在线状态,并具有积极的优先级。
推荐阅读
- javascript - 如何在以 Query 开头的组件中测试 onCompleted、onError 或 onSuccess
- python - 为什么我的机器人没有分配角色的权限?
- smlnj - 我可以在 Powershell 窗口中运行 smlnj repl,但是当我尝试使用文件运行它或在 REPL 中“使用”文件时,它会失败
- assembly - 将指令指针的当前值复制到另一个寄存器中
- dafny - dafny 断言违反错误,不知道是什么原因
- typescript - VueJs + TypeScript + Splitpanes 导入错误
- angular - RD-Navbar 的问题不适用于角度
- python - 访问被拒绝 - python selenium - 即使在使用 User-Agent 和其他标头之后
- java - 如何在 Java 中用条件编写正则表达式?
- java - Mono之间如何正确交互?