ASmack MultiUserChat ( MUC) не может прослушивать сообщения
У меня есть это приложение для Android, которое я пытался установить XMPP MultiUserChat.
Что касается подключения к XMPP, входа в систему и создания MUC (а также присоединения к уже созданному), все идет хорошо.
Кажется, мне просто не удается правильно прослушать отправленные сообщения, и я не уверен, почему.
Я несколько раз работал с XMPP с использованием Javascript ( StropheJS с Bosh), поэтому я немного знаком с его протоколами.
Как я уже попробовал, что предлагается в следующем посте (единственный пост, который я нашел по этому вопросу):
Как правильно слушать MultiUserChat в Smack?
Итак, я решил спросить вас о некоторых направлениях, так как я думаю, что это, вероятно, простая установка, которую я упускал все это время.
Итак, ради простоты, я собираюсь предоставить всю мою последовательность.
Я создал Службу, чтобы мое XMPP-соединение могло распространяться на все приложение. Поскольку мне нужно подключиться к XMPP, как только мое приложение войдет в систему, и комнаты MUC будут использоваться только дальше в других действиях. Ну, вы поняли. Итак, вот код:
(извините, если это слишком долго, я не хочу раздражать, все, что я хочу, это предоставить все необходимое, чтобы решить эту проблему)
//everything is alright here.
//it's connecting correctly to XMPP
public void connect()
{
Thread t = new Thread(new Runnable() {
@Override
public void run()
{
boolean flConnected = false;
System.setProperty("smack.debugEnabled", "true");
SmackConfiguration.setDefaultPacketReplyTimeout(10000);
ConnectionConfiguration ConnectionConfiguration = new ConnectionConfiguration(Host, Port);
ConnectionConfiguration.setSecurityMode(org.jivesoftware.smack.ConnectionConfiguration.SecurityMode.disabled);
ConnectionConfiguration.setDebuggerEnabled(true);
ConnectionConfiguration.setSendPresence(true);
connection = new XMPPTCPConnection(ConnectionConfiguration);
try
{
connection.connect();
login();
}
//there are many exceptions being treated, I
//suppressed them here for simplicity's sake
catch (Exception e)
{
Log.e(TAG, "connection exception: " + e.getMessage());
}
}
});
t.start();
}
public void login()
{
try
{
connection.login(this.User, Pwd);
Presence presence = new Presence(Presence.Type.available);
connection.sendPacket(presence);
this.setLoginAttempts();
}
catch (Exception e)
{
Log.e(TAG, "connection exception: "+e.getMessage());
}
}
Итак, когда пользователь должен быть администратором определенной чат-группы, я создаю группу, передающую имя группы (id)
public void createGroup(String strRoom)
{
try
{
muc = new MultiUserChat(connection, strRoom+"@"+this.GroupChat);
muc.create(this.User);
Form form = muc.getConfigurationForm();
Form submitForm = form.createAnswerForm();
for (Iterator fields = form.getFields().iterator(); fields.hasNext();) {
FormField field = (FormField) fields.next();
if (!FormField.TYPE_HIDDEN.equals(field.getType())
&& field.getVariable() != null) {
submitForm.setDefaultAnswer(field.getVariable());
}
}
List<String> owners = new ArrayList<>();
owners.add(this.User + "@"+this.Host);
muc.sendConfigurationForm(submitForm);
//here, it's another FAILED attempt of putting the
//listener to an async class. Didn't work at all!!
//just kept it here so you can see my attempts!
//new MessageRunner().execute(connection);
}
catch (Exception ex)
{
Log.e(TAG, " exception :"+ex.getMessage());
}
}
И когда он просто участник, он присоединяется к группе:
public void joinGroup(String strRoom)
{
try
{
DiscussionHistory history = new DiscussionHistory();
history.setMaxStanzas(50);
muc = new MultiUserChat(connection, strRoom+"@"+this.GroupChat);
muc.join(strRoom, this.Pwd, history, connection.getPacketReplyTimeout());
this.addMessageListener(muc);
this.listen2Group();
}
catch (Exception ex)
{
Log.e(TAG, "Exception :"+ex.getMessage());
}
}
Итак, у меня есть 3 метода, которые я использовал как попытки заставить пользователя правильно прослушать входящие сообщения.
Один из них устанавливается сразу после входа в систему: setListener(connection);
Два других вызывают после того, как пользователь присоединяется к GroupChat:
addMessageListener (MUC); и listen2Group ();
Я оставляю их всех здесь, чтобы вы могли видеть, как далеко я зашел:
private void addMessageListener(MultiUserChat muc)
{
//it's never coming here! never ever!!!
if(null != muc){
muc.addMessageListener(new PacketListener() {
@Override
public void processPacket(Packet packet) {
Log.i("processPacket", "receiving message");
}
});
}
}
private void listen2Group()
{
//also, NEVER EVER getting here at any time!!
PacketFilter filter = new MessageTypeFilter(Message.Type.groupchat);
connection.addPacketListener(new PacketListener() {
@Override
public void processPacket(Packet packet) throws NotConnectedException
{
Message message = (Message) packet;
if (message.getBody() != null)
{
//message should be treated here,
//but I suppressed it as well.
}
}
}, filter);
}
public void setListener(XMPPConnection cnx)
{
this.connection = cnx;
if (connection != null) {
PacketFilter filter = new MessageTypeFilter(Message.Type.groupchat);
connection.addPacketListener(new PacketListener() {
@Override
public void processPacket(Packet packet) {
Message message = (Message) packet;
if (message.getBody() != null)
{
//message will be treated here.
}
}
}, filter);
}
}
И вот как я отправляю сообщения:
public void sendMessage(String msgText)
{
try
{
Message msg = new Message();
msg.setBody(msgText);
msg.setType(Message.Type.groupchat);
muc.sendMessage(msg);
//I tried sending with this one as well, nope!
//connection.sendPacket(msg);
}
catch(Exception ex)
{
Log.e(TAG, " exception :"+ex.getMessage());
}
}
Так что, наверное, вы уже видели, где я делаю это неправильно. Но я работал над этим в течение нескольких дней. Ничего не приходит!
Когда я проверяю на своем сервере (openfire), все пользователи подключены к сети, они также правильно входят в MUC, когда сообщения отправляются, ничего не происходит!
Я ставлю контрольные точки на всех слушателей, которых я показывал тебе, но они никогда не срабатывают, что бы я ни делал. Сообщение отправлено, но оно никуда не приходит.
Есть идеи?
1 ответ
Для будущих ссылок (поскольку smack в его текущей версии не полностью документирован)
Я нашел, что было не так со слушателями!
Оказывается, я не устанавливал пункт назначения для чат-группы.
Поскольку по своей природе это групповой чат, я предположил, что ему не нужно настраивать получатель сообщений.
Все, что нужно было исправить, было у моего метода sendMessage, дополнительная строка:
msg.setTo (this.room + "@" + my_service_address);
http://xmpp.org/extensions/xep-0045.html
На XEP-0045 говорится, что для группового чата у него должен быть адрес получателя для правильной работы.
"Сообщения, отправляемые в многопользовательских комнатах чата, относятся к особому типу" групповой чат "и адресованы самой комнате (room@service), а затем отображаются всем посетителям"