【问题标题】:Duplicate messages receiving in android smack 4.1在 android smack 4.1 中接收到重复的消息
【发布时间】:2015-09-07 19:52:23
【问题描述】:

我一直在尝试使用 smack 4.1 创建一个 android 聊天应用程序。消息发送和接收工作正常,但问题是在 mXmppConnection.addAsyncStanzaListener 中多次收到相同的消息。我不知道我是否错过了向连接添加内容。

这是我的连接类:

XMPPTCPConnectionConfiguration.Builder configBuilder = new XMPPTCPConnectionConfiguration.builder();

 configBuilder.setUsernameAndPassword(mUser, "password@123");
configBuilder.setPort(5555);
configBuilder.setServiceName("tvm.myname.com");
configBuilder.setDebuggerEnabled(true);                    configBuilder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
try 
{
XMPPTCPConnection mConnection = new XMPPTCPConnection(configBuilder.build());
mConnection.connect();
mConnection.login();
} 
catch (SmackException e) 
{
} 

这是消息接收的代码:

mXmppConnection.addAsyncStanzaListener(new StanzaListener() {
 @Override
 public void processPacket(Stanza packet) throws SmackException.NotConnectedException {
 Message message = (Message)packet;  
  Log.i("XMPPClient", "****** message " + message);
  // code for handling message
}                  `enter code here`
},null);

真正的问题是我多次收到消息..消息的值多次打印在日志中。请帮帮我....

【问题讨论】:

  • 我们正在使用 PacketListener 来监听/接收来自 XMPP Chat Android 的消息。
  • @RajanBhavsar 感谢您的快速回复,但很遗憾地说 PacketListener 已被弃用。请看链接github.com/igniterealtime/Smack/wiki/…
  • 糟糕!最后它已被修复......问题不在于客户端,而是由于编码粗心。我一直在将连接对象的单个实例分配给类变量,并且监听器每次都添加到这些引用对象中。所以这会导致多次调用监听器......通过将监听器添加到单例连接对象来完成修复。
  • 请将此作为答案并将您的问题标记为已回答。
  • @Flow 您能否提供一些有关在 android 中使用 smack api 发送和接收 msg 的有用信息。谢谢

标签: android client xmpp chat smack


【解决方案1】:

终于找到解决方案

问题不在于客户端,而在于粗心的编码。我一直在将连接对象的单个实例分配给类变量,并且监听器每次都添加到这些引用对象中。所以这会导致多次调用监听器......通过将监听器添加到单例连接对象来完成修复。

【讨论】:

  • 您能否提供使用 smack api for android 发送和接收 msg 的 sn-p。将不胜感激。谢谢。
  • @DevendraSingh 请看下面的帖子
【解决方案2】:

我不知道是否有任何最佳方法可以在整个应用程序中保持 xmpp 连接稳定。如果有人知道更好的解决方案,请在此处发布答案。我使用的是全局连接变量,所有的聊天操作都是通过使用这个静态连接变量来完成的。这对我有用。 为了使用 smack 发送和接收消息,我们需要与 xmpp 服务器建立连接。

public static AbstractXMPPConnection getInstance(Context context) {
    mContext = context;
    sendMessageCallBack = (XmppSendMessageCallBack) context;
    if (mConnection == null) {
        mInstance = new XmppClient();
        mUser = new Preferences(context).getPhone();
        setUserToServer();
    }
    return mConnection;
} 


private static void setUserToServer() {

    new Thread(new Runnable() {
        @Override
        public void run() {             
            try {

                Looper.prepare();
                /** connecting  to server ***/
                XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder();
                configBuilder.setServiceName(Constants.HOST_URL);
                configBuilder.setDebuggerEnabled(true);
                configBuilder.setSendPresence(true);
                configBuilder.setConnectTimeout(XMPPTCPConnectionConfiguration.DEFAULT_CONNECT_TIMEOUT);
                configBuilder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
                String[] sslProtocols = {"starttls"
                        , "no_sslv3"
                        , "no_tlsv1"};
                configBuilder.setEnabledSSLProtocols(sslProtocols);

                mConnection = new XMPPTCPConnection(configBuilder.build());
                mConnection.setPacketReplyTimeout(120000);
                mConnection.connect();
                // Log into the server
                if(mConnection!=null) {
                    mConnection.login(mUser, "password@123");

                    reConnectionSetUp();

                    PingManager pingManager = PingManager.getInstanceFor(mConnection);
                    pingManager.setPingInterval(60000);
                    pingManager.pingMyServer();
                    pingManager.registerPingFailedListener(new PingFailedListener() {
                        @Override
                        public void pingFailed() {
                            if (mConnection != null && !mConnection.isConnected())
                                setUserToServer();
                        }
                    });
                    setUpListenersForXmppConnection(mConnection);
                }

            } catch (SmackException.ConnectionException e) {
                Log.e("XmppClient", "ConnectionException :", e);
                Toast.makeText(mContext,"failed to connect to server",Toast.LENGTH_SHORT).show();
            } catch (SmackException.NoResponseException e) {
                Log.e("XmppClient", "NoResponseException :", e);
                Toast.makeText(mContext,"Connection time out please try again",Toast.LENGTH_SHORT).show();
            } catch (XMPPException e) {
                Log.e("XmppClient", "XMPPException :", e);
            }catch (IOException e) {
                Log.e("XmppClient", "IOException :", e);
            }catch (SmackException.NotConnectedException e) {
                Log.e("XmppClient", "NotConnectedException :", e);
                reConnectionSetUp();
            }catch (SmackException e) {
                Log.e("XmppClient", "SmackException :", e);
            }catch (NullPointerException e) {
                Log.e("XmppClient", "NullPointerException :", e);
            }
        }

    }).start();
}


 private static void setUpListenersForXmppConnection(AbstractXMPPConnection xmppConnection){
    try {
        if(xmppConnection!=null) {

            sendOnlineStatus();

            /** adding connection listener **/
            xmppConnection.addConnectionListener(mInstance);

            /** adding privacy manager to connection  **/
            if(xmppConnection!=null)
                mPrivacyListManager = PrivacyListManager.getInstanceFor(xmppConnection);
            /** adding packet listener for receving incoming packets **/
            StanzaFilter filter = MessageTypeFilter.NORMAL;

            if(xmppConnection!=null && mInstance!=null)
                xmppConnection.addSyncStanzaListener(mInstance, null);                            

        }
    } catch (SmackException e) {
        Log.e("XmppClient", "IOException :", e);
    } catch (XMPPException e) {
        Log.e("XmppClient", "XMPPException :", e);
        e.printStackTrace();
    } catch (NullPointerException e) {
        Log.e("XmppClient", "NullPointerException :", e);
    } catch (ConcurrentModificationException e){
        Log.e("XmppClient", "ConcurrentModificationException :", e);
    } catch (IllegalArgumentException e){
        e.printStackTrace();
    }catch (RetrofitError e){
        Log.e("XmppClient", "RetrofitError :", e);
    }

}

当我们收到消息时,将调用以下方法

   @Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException {

    if(packet instanceof Message) {
        Message message = (Message) packet;
        // Do your task

    }
}

我们可以像这样创建一个smack的消息对象来发送消息,

  Message message = new Message();
    message.setFrom(senderId);
    message.setBody(body);
    message.setSubject(subject);
    message.setTo(receiverId);

 try {
        if(mConnection!=null){
            ChatManager chatManager = ChatManager.getInstanceFor(mConnection);
            if(chatManager!=null){
                chatManager.createChat(message.getTo(), new ChatStateListener() {
                    @Override
                    public void stateChanged(Chat chat, ChatState state) {
                        Log.e("XMPPClient", "******* stateChanged "+state);
                    }
                    @Override
                    public void processMessage(Chat chat, Message message) {
                        Log.e("XMPPClient", "******* processMessage "+message.getSubject());
                    }
                }).sendMessage(message);
            }
        }
        sendMessageCallBack.messageSuccessfullySend(message.getStanzaId(), status);

    }catch (SmackException.NotConnectedException e){
        Log.e("XMPPClient", "******* NotConnectedException ", e);
        sendMessageCallBack.messageSendingFailed("");

    }catch(NullPointerException e){
        Log.e("XMPPClient", "******* NullPointerException ", e);
        sendMessageCallBack.messageSendingFailed("");
    }catch (Exception e){
        sendMessageCallBack.messageSendingFailed("No Network");
    }

【讨论】:

  • 当您关闭应用程序或系统杀死应用程序时,这是否有效?
【解决方案3】:

只需使用addSyncStanzaListener 代替addAsyncStanzaListener

【讨论】:

    【解决方案4】:

    我遇到了同样的问题,但我得到了解决方案,当您从应用程序注销时,您没有取消注册您的 BroadcastReceiver 是注销代码,并且您使所有连接都是单例的。

    try {
    Presence pr=new Presence(Presence.Type.unavailable);
    pr.setStatus(RoosterConnection.getConnection().getUser() + "false");
    RoosterConnection.getConnection().sendStanza(pr);
    if (mConnection != null) {
    mConnection.disconnect();
    }
        //  mBus.unregister(this);
        mConnection = null;
    // Unregister the message broadcast receiver.
    if (uiThreadMessageReceiver != null) {
    mApplicationContext.unregisterReceiver(uiThreadMessageReceiver);
    uiThreadMessageReceiver = null;
    }
    
    Intent intent = new Intent(this,LoginActivity.class);
    startActivity(intent);
    finish();}catch(SmackException.NotConnectedException e){    e.printStackTrace();}catch(InterruptedException e){
    e.printStackTrace();}
    

    【讨论】:

      猜你喜欢
      • 2016-10-26
      • 2016-05-12
      • 2017-07-21
      • 2016-06-01
      • 1970-01-01
      • 2017-04-04
      • 2016-02-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多