在 android smack 4.1 中收到重复消息
Duplicate messages receiving in android smack 4.1
我一直在尝试使用 smack 4.1 创建一个 android 聊天应用程序。消息发送和接收工作正常,但问题是同一条消息在 mXmppConnection.addAsyncStanzaListener.I 中多次出现,不知道我是否错过了向连接添加内容。
这是我的连接class:
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);
真正的问题是我多次收到消息。消息的值多次打印在日志中。请帮助我....
终于找到解决方案
问题不在于客户端,而是由于粗心的编码。我一直在将连接对象的单个实例分配给 class 变量,并且监听器每次都添加到这些引用对象中。因此导致多次调用侦听器....修复是通过将侦听器添加到单例连接对象来完成的。
我不知道有没有什么最好的方法可以在 application.If 期间保持 xmpp 连接稳定。如果有人知道更好的解决方案,请 post 在这里回答。我正在使用一个全局连接变量,所有的聊天操作都是通过使用这个静态连接变量来完成的。这对我有用。
要使用 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");
}
只需使用 addSyncStanzaListener
代替 addAsyncStanzaListener
我遇到过同样的问题,但我得到了解决方案,当你从下面的应用程序注销时,你没有注销你的 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();}
我一直在尝试使用 smack 4.1 创建一个 android 聊天应用程序。消息发送和接收工作正常,但问题是同一条消息在 mXmppConnection.addAsyncStanzaListener.I 中多次出现,不知道我是否错过了向连接添加内容。
这是我的连接class:
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);
真正的问题是我多次收到消息。消息的值多次打印在日志中。请帮助我....
终于找到解决方案
问题不在于客户端,而是由于粗心的编码。我一直在将连接对象的单个实例分配给 class 变量,并且监听器每次都添加到这些引用对象中。因此导致多次调用侦听器....修复是通过将侦听器添加到单例连接对象来完成的。
我不知道有没有什么最好的方法可以在 application.If 期间保持 xmpp 连接稳定。如果有人知道更好的解决方案,请 post 在这里回答。我正在使用一个全局连接变量,所有的聊天操作都是通过使用这个静态连接变量来完成的。这对我有用。 要使用 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");
}
只需使用 addSyncStanzaListener
代替 addAsyncStanzaListener
我遇到过同样的问题,但我得到了解决方案,当你从下面的应用程序注销时,你没有注销你的 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();}