Android Smack MUC 400 错误请求发送群聊消息

Posted

技术标签:

【中文标题】Android Smack MUC 400 错误请求发送群聊消息【英文标题】:Android Smack MUC 400 Bad Request sending group Chat Message 【发布时间】:2016-09-20 11:12:56 【问题描述】:

嘿,我正在使用 XMPP Smack 库开发聊天应用程序。最近我正在处理群聊,在发送群消息时,一些消息将被丢弃,因此接收者不会收到来自发送方的消息。它会给我 400 个错误的请求。

它有时会起作用。有时不工作

在这里我在 400 bad request 中发现了这种消息。

<?xml version="1.0" encoding="UTF-8"?>
<message to="156@abc.com/android" id="nXlV6-1144" type="error" from="24@confrence.abc.com/156@abc.com.com">
   <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>

如果成功发送消息,它会给出这种消息。

<?xml version="1.0" encoding="UTF-8"?>
<message to="156@abc.com/Android" id="nXlV6-1411" type="groupchat" from="24@conference.abc.com/156@abc.com">
   <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>

如何持续发送消息?任何的想法? 提前谢谢你。

这是我发送 muc 消息的代码:

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;
        

【问题讨论】:

【参考方案1】:

@LearnPainLess,请按照以下步骤解决群聊问题

-创建群组时,将群组的jid保存在数据库中,如“somegroup@conference.domain.com”

-创建用于创建 xmpp 连接的后台任务(这样它将始终连接)

-登录xmpp后,从数据库中获取组名并连接

另外,在 openfire 中,群聊 > 群聊设置 > 编辑图标 > 默认房间设置 > 选中“使房间持久化”

另外,在其他设置中>永远不要踢空闲用户

【讨论】:

谢谢它有效。但我的消息没有收到任何用户。 还去 openfire > 服务器设置选项卡 > 离线消息(左侧菜单)> 检查存储、存储或丢弃(并设置每个用户的最大大小),你也设置了数据包监听器或用于接收数据包的节侦听器 感谢您的帮助。 :) 你能上传群聊的工作演示吗?这对我很有帮助。 我正在使用 4.1.0.. 是的.. 我将分享我的 xmpp 基类和一个小演示.. 但是明天,因为我是办公室里唯一剩下的人 :p ..发邮件给我 zainullahdev@outlook.com 我会回复的 你好@zain ullah,我尝试了你建议在 OpenFire 服务器上修改的内容,但一段时间后我的聊天组仍然删除。【参考方案2】:

我有一个 XmppBase 类,我将所有的 xmpp 代码放在其中

单独文件夹中的所有侦听器

连接存储在静态变量中,我使用

检索它

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;
        

    

每当我想发送消息时,我都会调用它

public static Boolean sendMUCChatMsg(Message msg)

    if(multiUserChat != null)
        try 
            multiUserChat.sendMessage(msg);

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

对不起,如果它看起来很笨拙,如果我错过了那里的任何功能,请告诉我,但这是我正在使用的工作代码

【讨论】:

你能告诉我如何邀请朋友吗?一段时间后,GroupChat 从 openfire 中删除。你能帮忙吗? 是的,邀请朋友查看我对这个问题的另一个答案,我现在将添加。对于群聊,我为 xmpp 连接做了一个后台服务,所以请按照以下步骤操作: 抱歉无法输入评论,我会为此发布新答案【参考方案3】:

试试这个,

我修改了你的最后一个函数

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);

【讨论】:

【参考方案4】:

我正在 MUC 中处理“已看到并已交付”,并在使用相同的数据包 ID 回复时遇到此问题,仍在测试,但我认为在您的情况下,您应该将您的 xmpp 连接移动到后台服务并在连接到 xmpp 后在设备启动时,连接到数据库中的所有 muc。这样,您将始终与群组保持联系。

原因:根据我的说法,当其他用户未连接到 muc 并且您发送消息或回复具有相同数据包 ID 的组时。

注意:我使用 multiuserchat.sendmessage 发送群消息和 chat.sendmessage 发送消息给单个用户

SMACK 4.1

** 更新**

我通过创建新数据包而不是修改我收到的数据包来修复它

这是包裹

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

在您的情况下,请先尝试使用简单数据包。如果一切正常,然后一个一个添加扩展,看看你在哪里得到错误,谢谢

【讨论】:

嗨,我认为这是相同的数据包问题,但我仍然确认使用多用户发送消息的片段代码进行更新...我也有连接问题,它多次断开连接 我遇到了断线问题,但是当我将其移至后台服务时,它已修复。还有一件事,如果您使用的是openfire服务器,请启用存档聊天,并在您发送“错误请求”消息后查看用户是否断开连接,您还应该使用yourmuc.sendmessage而不是chat.sendmessage发送群组消息。注意:发送消息时不要指定 TOFROM 我从片段代码中看到您首先连接到 muc 然后发送消息。因此,对于下一条消息,它将重新连接您,然后尝试发送消息。分开这两个逻辑:打开聊天窗口时检查 multiuserchat 是否为空,如果是,则使用 getMultiUserChat() 连接到 muc 我将用我的代码添加另一个答案 我也在更新我的后台服务代码,让你更了解我哪里出错了

以上是关于Android Smack MUC 400 错误请求发送群聊消息的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Smack 确定 MUC 是不是存在?

smack 使用 4.1.0 rc1 在 muc 中接收消息

如何使用 SMACK OMEMO 为群聊或 MUC 生成指纹?

Smack MUC 邀请

xmpp/smack : muc(MultiUserChat:多人聊天)房间配置表单

使用 xmpp 在 muc 中创建空间时出错