1
votes

Hey i am developing Chat Application using XMPP Smack Library. Recently i am working on Group Chat While sending Group message some message will be drop so receiver wouldn't receives message from the sender side. it will gives me 400 bad request.

it is working sometimes. and sometimes not work

here i found this kind of message in 400 bad request.

<?xml version="1.0" encoding="UTF-8"?>
<message to="[email protected]/Android" id="nXlV6-1144" type="error" from="[email protected]/[email protected]">
   <received xmlns="urn:xmpp:receipts" id="nXlV6-1142" />
   <error code="400" type="modify">
      <bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
   </error>
</message>

if successfully send message it will give this kind of message.

<?xml version="1.0" encoding="UTF-8"?>
<message to="[email protected]/Android" id="nXlV6-1411" type="groupchat" from="[email protected]/[email protected]">
   <body>eyu4u4</body>
   <chatDetail xmlns="jabber:x:oob">
      <UID>156</UID>
      <time>04:20 PM</time>
      <user_icon>24_group_icon.jpg</user_icon>
      <SentTime>1474368652960</SentTime>
      <USERName>vasudev89</USERName>
      <user_name>cryan</user_name>
      <message>eyu4u4</message>
      <type>group</type>
      <phone_number>24</phone_number>
   </chatDetail>
   <request xmlns="urn:xmpp:receipts" />
</message>

how i can send message persistently? Any idea? Thank You in Advance.

here is my code sending muc message:

public boolean sendGroupMessage(Message message, String strGroupID) {

            DeliveryReceiptRequest.addTo(message);
            try {
                Log.i(TAG, "sendGroupMessage");
                //Log.i("JOIN MUC","To join group chat: " + groupChat.getClassId());

                // Get the MultiUserChatManager
                MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(AbstractXMPPConnection);

                // Create a MultiUserChat using an XMPPConnection for a room
                MultiUserChat muc = manager.getMultiUserChat(strGroupID + AppWSConstants.XMPP_JID_GROUP_CHAT_SUFFIX);
                muc.sendMessage(message);
                return true;
            } catch (NotConnectedException e) {
                e.printStackTrace();
            }
            return false;
        }
4

4 Answers

2
votes

@LearnPainLess, follow these steps to solve group chat issue

-when creating groups, save the jid of group in the database, like "somegroup@conference.{domain}.com"

-create background task for creating xmpp connection (this way it will always be connected)

-after logging in to xmpp, get the group names from the database and connect to them

also, in openfire, Group Chat > Group Chat Settings > Edit Icon > Default Room Settings > Check "Make Room Persistant"

also, in other settings > Never kick idle users

0
votes

I have an XmppBase class where i put all my xmpp code

All listeners in seperate folder

Connection is stored in static variable and i retrive it using

Utils.getConnection()

// this function m calling from background service and everywhere if not connectect to xmpp
public static XMPPConnection CreateXmppConnection() {
    if (Utils.getConnection() == null) {
        try {
            Boolean isConnected = new XmppAsync(mUsername, mPassword,context).execute().get();
            if (isConnected && Utils.getConnection() != null) {
                RegisterConnListeners(Utils.getConnection());
                updateMyProfileImg();

                // connect to all groups
                DBAdapter adapter = new DBAdapter(context);
                adapter.openForRead();
                List<UserDetail> groups = new ArrayList<>();
                adapter.addAllGroups(groups);
                adapter.addPastChatGroups(groups);
                adapter.close();

                for(UserDetail g : groups)
                {
                    CreateXmppMUCSession(g.getGroupTemp());
                }

                return Utils.getConnection();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        return null;
    } else
        return Utils.getConnection();
}

// get muc chat manager
public static MultiUserChatManager getMucManager() {

    if(mucManager != null)
        return mucManager;

    if (Utils.getConnection() != null) {
        return MultiUserChatManager.getInstanceFor(Utils.getConnection());
    } else {
        if (CreateXmppConnection() != null)
            return MultiUserChatManager.getInstanceFor(Utils.getConnection());
        else {
            Log.v("error", "Some Error Occured");
            Toast.makeText(context, "Cant Connect to Xmpp", Toast.LENGTH_SHORT).show();
            return null;
        }

    }

}

// create muc session and m passing group name - call when you open chat page
public static void CreateXmppMUCSession(String gName)
{
    RegisterGroupChatListeners(gName);
}

// connect to muc if not already connected
public static void RegisterGroupChatListeners(String groupName)
{
    try {
        mStateManager = getChatStateManager();
        multiUserChat = getMUC(groupName);
        //  if(multiUserChat != null) {
        multiUserChat.addMessageListener(new MyMUCMessageListener());
        try {
            if (!multiUserChat.isJoined()) {
                DiscussionHistory discussionHistory = new DiscussionHistory();
                discussionHistory.setMaxStanzas(0);
                multiUserChat.join(new MyPrefrence(context).getUsername().split("@")[0], "123",
                        discussionHistory, SmackConfiguration.getDefaultPacketReplyTimeout());
            }
        } catch (SmackException.NoResponseException e) {
            e.printStackTrace();
        } catch (XMPPException.XMPPErrorException e) {
            e.printStackTrace();
        } catch (SmackException.NotConnectedException e) {
            e.printStackTrace();
        }
        //  }
    }
    catch (Exception ex)
    {
        //
    }

}

// get muc 
public static MultiUserChat getMUC(String groupName)
{
  //  Log.v("nick",multiUserChat.getNickname() + " , g = " + groupName);
  //  if(multiUserChat != null && multiUserChat.getRoom().contains(groupName))
  //  {
  //      return multiUserChat;
  //  }

    if (Utils.getConnection() != null) {
        MultiUserChatManager chatManager = getMucManager();
        if (chatManager != null) {
            return chatManager.getMultiUserChat(groupName);
        } else {
            Toast.makeText(context, "Cannot create Chat", Toast.LENGTH_SHORT).show();
            return null;
        }
    } else {
        if (CreateXmppConnection() != null) {
            MultiUserChatManager chatManager = getMucManager();
            if (chatManager != null) {
                return chatManager.getMultiUserChat(groupName);
            } else {
                Toast.makeText(context, "Cannot create Chat", Toast.LENGTH_SHORT).show();
                return null;
            }
        }
        else {
            Toast.makeText(context, "Cannot create Chat", Toast.LENGTH_SHORT).show();
            return null;
        }

    }
}

and whenever i want to send message i just call this

public static Boolean sendMUCChatMsg(Message msg)
{
    if(multiUserChat != null)
        try {
            multiUserChat.sendMessage(msg);

            return true;
        } catch (SmackException.NotConnectedException e) {
            e.printStackTrace();
        }
    return false;
}

Sorry if it looks clumpsy, if I missed any function there let me know, but this is working code which i am using

0
votes

try this,

I modified your last function

static MultiUserChat multiUserChat;
// call this function when you open the chat window
private void CreateGroupConnection(String strGroupID ) {

// Get the MultiUserChatManager
            MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(AbstractXMPPConnection);

            // Create a MultiUserChat using an XMPPConnection for a room
            MultiUserChat multiUserChat = manager.getMultiUserChat(strGroupID + AppWSConstants.XMPP_JID_GROUP_CHAT_SUFFIX);

return multiUserChat;
}

// whenever sending message from chat call this

publilc static void sendMucMessage(Message message){
 if(multiUserChat != null)
 multiUserChat.sendMessage(message);
}
0
votes

I am working on "seen and delivered" in MUC and facing with this issue when replying back with the same packet id, still testing but I think in your case you should move your xmpp connection to background service and after connecting to xmpp on device launch up, connect to all the muc in your database. This way you will always be connected to groups.

cause : according to me, when the other user is not connected to the muc and you send a message or when you reply to the group with the same packet id.

Note: I am using multiuserchat.sendmessage to send group message and chat.sendmessage to send message to single user

SMACK 4.1

** update **

I fixed it by creating new packet instead of modifying the one i am receiving

here is the packet

Message msgg = new Message();
msgg.setBody(message.getPacketID());
msgg.setSubject(MessageModel.CHAT_STATUS_SEEN + "");
XmppBase.sendMUCChatMsg(msgg);

in your case, try with simple packet first. if all works well, then add extension one by one and see where you get the error, Thanks