Can't update a MUC name after creating it

Hi,

updating a MUC name right after I’ve creating it doesn’t work, even if I try many times.

I’m updating the name using:

            val muc = mucManager.getMultiUserChat(roomJid)
            val form = muc.configurationForm.fillableForm
            form.setAnswer("muc#roomconfig_roomname", title)
            ...
            muc.sendConfigurationForm(form)

No exception is thrown.

The problem seems to be that the getRoomInfo method (I’m using it to retrieve the MUC info, such as its title) of the MultiUserChatManager always returns the previous (and old) MUC name.

If I try renaming a MUC after a logout/ login everything works correctly. Should I call some specific method to “refresh” the subscribed MUCs?

I’m using Smack Android client version 4.4.8.

If you look at the implementation of MultiUserChatManager.getRoomInfo(Jid) you see that it essentially just a wrapper around a service discovery request. However, this request may used cached information.

I suggest you

  1. attach a breakpoint at the method and see where the DiscoverInfo is obtained
  2. set SmackConfiguration.DEBUG to true, to look at the actual stanzas that go over the wire

See also

That would be a little bit besides the point of using a library. That said, could be that caps caching is involved here, but the cache should update eventually.

A full XMPP trace starting from the point where you change the MUC name and ending after you call MultiUserChatManager.getRoomInfo(Jid) would provide valueable insight.

Thank you for your help.
I also thought something about the cache, that could explain why a logout/ login solves everything for an already created MUC.

Another strange thing is that if I create a MUC and try to rename it, I cannot see the name update, but all the other users inside the MUC can see it instantly. It doesn’t work only for the user who tried the update.

Below you can find the trace printed.

  • user1 is the creator of the MUC and the one who’s trying to update the MUC name

  • user2 is the only other user in the MUC

  • user1 tried renaming the MUC from mucTest1 to mucTest2

Smack Debug trace
SENT (0): 
<iq to='efvw8qkrhsvm6e1e@conference.chat-1.myDomain.it' id='E7GYZ-346' type='get'>
  <query xmlns='http://jabber.org/protocol/muc#owner'>
  </query>
</iq>
RECV (0): 
<iq xml:lang='en-US' to='user1_myDomain.it@chat-1.myDomain.it/MobileChat' from='efvw8qkrhsvm6e1e@conference.chat-1.myDomain.it' type='result' id='E7GYZ-346'>
  <query xmlns='http://jabber.org/protocol/muc#owner'>
    <x type='form' xmlns='jabber:x:data'>
      <title>
        Configuration of room efvw8qkrhsvm6e1e@conference.chat-1.myDomain.it
      </title>
      <field var='FORM_TYPE' type='hidden'>
        <value>
          http://jabber.org/protocol/muc#roomconfig
        </value>
      </field>
      <field var='muc#roomconfig_roomname' type='text-single' label='Room title'>
        <value>
          mucTest1
        </value>
      </field>
      <field var='muc#roomconfig_roomdesc' type='text-single' label='Room description'/>
      <field var='muc#roomconfig_lang' type='text-single' label='Natural Language for Room Discussions'>
        <value>
          en
        </value>
      </field>
      <field var='muc#roomconfig_persistentroom' type='boolean' label='Make room persistent'>
        <value>
          1
        </value>
      </field>
      <field var='muc#roomconfig_publicroom' type='boolean' label='Make room public searchable'>
        <value>
          0
        </value>
      </field>
      <field var='public_list' type='boolean' label='Make participants list public'>
        <value>
          1
        </value>
      </field>
      <field var='muc#roomconfig_passwordprotectedroom' type='boolean' label='Make room password protected'>
        <value>
          0
        </value>
      </field>
      <field var='muc#roomconfig_roomsecret' type='text-private' label='Password'/>
      <field var='muc#roomconfig_maxusers' type='list-single' label='Maximum Number of Occupants'>
        <value>
          2000
        </value>
        <option label='5'>
          <value>
            5
          </value>
        </option>
        <option label='10'>
          <value>
            10
          </value>
        </option>
        <option label='20'>
          <value>
            20
          </value>
        </option>
        <option label='30'>
          <value>
            30
          </value>
        </option>
        <option label='50'>
          <value>
            50
          </value>
        </option>
        <option label='100'>
          <value>
            100
          </value>
        </option>
        <option label='200'>
          <value>
            200
          </value>
        </option>
        <option label='500'>
          <value>
            500
          </value>
        </option>
        <option label='1000'>
          <value>
            1000
          </value>
        </option>
        <option label='2000'>
          <value>
            2000
          </value>
        </option>
      </field>
      <field var='muc#roomconfig_whois' type='list-single' label='Present real Jabber IDs to'>
        <value>
          anyone
        </value>
        <option label='Moderators Only'>
          <value>
            moderators
          </value>
        </option>
        <option label='Anyone'>
          <value>
            anyone
          </value>
        </option>
      </field>
      <field var='muc#roomconfig_presencebroadcast' type='list-multi' label='Roles for which Presence is Broadcasted'>
        <value>
          moderator
        </value>
        <value>
          participant
        </value>
        <value>
          visitor
        </value>
        <option label='Moderator'>
          <value>
            moderator
          </value>
        </option>
        <option label='Participant'>
          <value>
            participant
          </value>
        </option>
        <option label='Visitor'>
          <value>
            visitor
          </value>
        </option>
      </field>
      <field var='muc#roomconfig_membersonly' type='boolean' label='Make room members-only'>
        <value>
          1
        </value>
      </field>
      <field var='muc#roomconfig_moderatedroom' type='boolean' label='Make room moderated'>
        <value>
          1
        </value>
      </field>
      <field var='members_by_default' type='boolean' label='Default users as participants'>
        <value>
          1
        </value>
      </field>
      <field var='muc#roomconfig_changesubject' type='boolean' label='Allow users to change the subject'>
        <value>
          1
        </value>
      </field>
      <field var='allow_private_messages' type='boolean' label='Allow users to send private messages'>
        <value>
          1
        </value>
      </field>
      <field var='allow_private_messages_from_visitors' type='list-single' label='Allow visitors to send private messages to'>
        <value>
          anyone
        </value>
        <option label='Nobody'>
          <value>
            nobody
          </value>
        </option>
        <option label='Moderators Only'>
          <value>
            moderators
          </value>
        </option>
        <option label='Anyone'>
          <value>
            anyone
          </value>
        </option>
      </field>
      <field var='allow_query_users' type='boolean' label='Allow users to query other users'>
        <value>
          1
        </value>
      </field>
      <field var='muc#roomconfig_allowinvites' type='boolean' label='Allow users to send invites'>
        <value>
          1
        </value>
      </field>
      <field var='allow_visitor_status' type='boolean' label='Allow visitors to send status text in presence updates'>
        <value>
          1
        </value>
      </field>
      <field var='allow_visitor_nickchange' type='boolean' label='Allow visitors to change nickname'>
        <value>
          1
        </value>
      </field>
      <field var='allow_voice_requests' type='boolean' label='Allow visitors to send voice requests'>
        <value>
          1
        </value>
      </field>
      <field var='allow_subscription' type='boolean' label='Allow subscription'>
        <value>
          1
        </value>
      </field>
      <field var='voice_request_min_interval' type='text-single' label='Minimum interval between voice requests (in seconds)'>
        <value>
          1800
        </value>
      </field>
      <field var='muc#roomconfig_pubsub' type='text-single' label='XMPP URI of Associated Publish-Subscribe Node'>
        <value/>
      </field>
      <field var='enable_hats' type='boolean' label='Enable hats'>
        <value>
          0
        </value>
      </field>
      <field var='mam' type='boolean' label='Enable message archiving'>
        <value>
          1
        </value>
      </field>
    </x>
  </query>
</iq>
app_time_stats: avg=201.84ms min=5.60ms max=519.30ms count=5
SENT (0): 
<iq to='efvw8qkrhsvm6e1e@conference.chat-1.myDomain.it' id='E7GYZ-348' type='set'>
  <query xmlns='http://jabber.org/protocol/muc#owner'>
    <x xmlns='jabber:x:data' type='submit'>
      <field var='FORM_TYPE'>
        <value>
          http://jabber.org/protocol/muc#roomconfig
        </value>
      </field>
      <field var='muc#roomconfig_whois'>
        <value>
          anyone
        </value>
      </field>
      <field var='muc#roomconfig_persistentroom'>
        <value>
          1
        </value>
      </field>
      <field var='muc#roomconfig_roomname'>
        <value>
          mucTest2
        </value>
      </field>
      <field var='muc#roomconfig_membersonly'>
        <value>
          1
        </value>
      </field>
      <field var='muc#roomconfig_publicroom'>
        <value>
          0
        </value>
      </field>
      <field var='muc#roomconfig_allowinvites'>
        <value>
          1
        </value>
      </field>
      <field var='allow_query_users'>
        <value>
          1
        </value>
      </field>
    </x>
  </query>
</iq>
RECV (0): 
<r xmlns='urn:xmpp:sm:3'/>
SENT (0): 
<a xmlns='urn:xmpp:sm:3' h='952'/>
RECV (0): 
<message to='user1_myDomain.it@chat-1.myDomain.it' from='efvw8qkrhsvm6e1e@conference.chat-1.myDomain.it' id='14659590577170521491'>
  <archived by='user1_myDomain.it@chat-1.myDomain.it' id='1715324599230245' xmlns='urn:xmpp:mam:tmp'/>
  <stanza-id by='user1_myDomain.it@chat-1.myDomain.it' id='1715324599230245' xmlns='urn:xmpp:sid:0'/>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <items node='urn:xmpp:mucsub:nodes:config'>
      <item id='14659590577170521491'>
        <message to='user1_myDomain.it@chat-1.myDomain.it' from='efvw8qkrhsvm6e1e@conference.chat-1.myDomain.it' type='groupchat' id='6205216861088648078' xmlns='jabber:client'>
          <x xmlns='http://jabber.org/protocol/muc#user'>
            <status code='104'/>
          </x>
        </message>
      </item>
    </items>
  </event>
</message>
RECV (0): 
<r xmlns='urn:xmpp:sm:3'/>
SENT (0): 
<a xmlns='urn:xmpp:sm:3' h='953'/>
RECV (0): 
<iq xml:lang='en-US' to='user1_myDomain.it@chat-1.myDomain.it/MobileChat' from='efvw8qkrhsvm6e1e@conference.chat-1.myDomain.it' type='result' id='E7GYZ-348'/>
Owner FocusChanged(false)
RECV (0):
<r xmlns='urn:xmpp:sm:3'/>
SENT (0):
<a xmlns='urn:xmpp:sm:3' h='954'/>
SENT (0):
<iq to='efvw8qkrhsvm6e1e@conference.chat-1.myDomain.it' id='E7GYZ-350' type='get'>
  <vCard xmlns='vcard-temp'/>
</iq>
RECV (0):
<iq xml:lang='en-US' to='user1_myDomain.it@chat-1.myDomain.it/MobileChat' from='efvw8qkrhsvm6e1e@conference.chat-1.myDomain.it' type='error' id='E7GYZ-350'>
  <vCard xmlns='vcard-temp'/>
  <error type='cancel'>
    <item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>
RECV (0):
<r xmlns='urn:xmpp:sm:3'/>
SENT (0):
<a xmlns='urn:xmpp:sm:3' h='955'/>
SENT (0):
<iq to='efvw8qkrhsvm6e1e@conference.chat-1.myDomain.it' id='E7GYZ-352' type='get'>
  <subscriptions xmlns='urn:xmpp:mucsub:0'>
  </subscriptions>
</iq>
RECV (0):
<iq xml:lang='en-US' to='user1_myDomain.it@chat-1.myDomain.it/MobileChat' from='efvw8qkrhsvm6e1e@conference.chat-1.myDomain.it' type='result' id='E7GYZ-352'>
  <subscriptions xmlns='urn:xmpp:mucsub:0'>
    <subscription nick='user2_myDomain.it' jid='user2_myDomain.it@chat-1.myDomain.it'>
      <event node='urn:xmpp:mucsub:nodes:messages'/>
      <event node='urn:xmpp:mucsub:nodes:subscribers'/>
      <event node='urn:xmpp:mucsub:nodes:config'/>
    </subscription>
    <subscription nick='user1_myDomain.it' jid='user1_myDomain.it@chat-1.myDomain.it'>
      <event node='urn:xmpp:mucsub:nodes:messages'/>
      <event node='urn:xmpp:mucsub:nodes:subscribers'/>
      <event node='urn:xmpp:mucsub:nodes:config'/>
    </subscription>
  </subscriptions>
</iq>
RECV (0):
<r xmlns='urn:xmpp:sm:3'/>
SENT (0):
<a xmlns='urn:xmpp:sm:3' h='956'/>```

Hi,
I have a similar problem. Did you find any solution?

Hi,
no, not yet.
As I said above, it only works after a reconnection (disconnect/ connect).

It seems that some sort of cache of the ServiceDiscoveryManager is involved here, but I honestly don’t know how to “refresh” or clear this cache.

Then I will check if there’s a way to update the ServiceDiscoveryManager. Thanks for the hint.
@Flow do you have any suggestion? Maybe something I can test or a workaround.
Thanks

It is possible that the xmpp trace is incomplete, at leat there are no disco#info related stanzas exchanged, nor the presence update of the MUC due its name change.

Furthermore, I can not reproduce this on Smack’s master using the following integration test:

    @SmackIntegrationTest
    public void mucTestChangeRoomName() throws XmppStringprepException, MucAlreadyJoinedException, MissingMucCreationAcknowledgeException, NotAMucServiceException, NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException, TestNotPossibleException {
        final EntityBareJid mucAddress = getRandomRoom("smack-inttest-change-room-name");
        final MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress);
        final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString);

        createMuc(mucAsSeenByOne, nicknameOne);
        try {
            String initialRoomName = "Initial Room Name";
            mucAsSeenByOne.getConfigFormManager().setRoomName(initialRoomName).submitConfigurationForm();
            RoomInfo roomInfo = mucManagerOne.getRoomInfo(mucAddress);
            assertEquals(initialRoomName, roomInfo.getName());

            String newRoomName = "New Room Name";
            mucAsSeenByOne.getConfigFormManager().setRoomName(newRoomName).submitConfigurationForm();
            roomInfo = mucManagerOne.getRoomInfo(mucAddress);
            assertEquals(newRoomName, roomInfo.getName());
        } catch (MucConfigurationNotSupportedException e) {
            throw new TestNotPossibleException(e);
        } finally {
            tryDestroy(mucAsSeenByOne);
        }
    }

Hi,

in your test, you’re using a method that is not released yet (mucAsSeenByOne.getConfigFormManager().setRoomName(newRoomName)) .
Could you please rewrite your integration test using the same methods that I’m using (the snippet I shared in the first message)?

Under the hood everything seems to be the same, but the fillableForm used could be the problem.

Just be 100% sure, this is how I create a new MUC:

    fun createMUC(title: String, vararg users: String): String? {
        return try {
            val roomName = generateRoomName()
            val bareJid = roomName.plus("@").plus(settings.mucDomain)
            val roomJid = JidCreate.entityBareFrom(bareJid)
            if (mucSubManager.subscribeToMuc(settings.entityBareJid, roomJid, getNickname().toString()).result) {
                val muc = mucManager.getMultiUserChat(roomJid)
                val confBuilder = muc.getEnterConfigurationBuilder(getNickname())!!
                    .requestNoHistory()
                if (!muc.isJoined) {
                    try {
                        muc.join(confBuilder.build())
                    } catch (e: Exception) { }
                }
                muc.grantModerator(getNickname())
                val info = setRoomInfo(roomJid, title)
                if (info) {
                    inviteUsers(roomJid, *users)
                    bareJid
                } else null
            } else null
        } catch (e: Exception) {
            null
        }
    }

setRoomInfo is the method I shared in the first message

Hi @Flow, have you had the chance to try with version 4.4.8 and not with the master code?

do you have any idea when the new version will be released?

We don’t have a guranteed release schedule. However, it is always possible to sponsor a release if you need one. Feel free to contact me for details.

This topic was automatically closed 62 days after the last reply. New replies are no longer allowed.