Smack lost connection while message proccessing - xmpp

I have the following problem
//The XMPP server sent 100 messages
ChatManager.getInstanceFor( connection ).addChatListener( new ChatManagerListener() {
#Override
public void chatCreated( Chat chat, boolean b ) {
chat.addMessageListener( ( Chat chat1, Message message ) -> {
// some slow processing, and on processing message number 75 the client is shutdown.
} );
}
} );
25 messages are lost. For they were delivered to client, but have not yet been processed.
Is there any way to notify the XMPP Server manually, on receiving these messages?

Related

Google PubSub ACK not received after processing few messages

We are using gcloud pub-sub 1.102.0 release.
Problem :- We have around 8K messages to process. We have 3 subscribers running in 3 different k8s pods and we are doing stream pulling. We are receiving the ACK for few messages (around 100) from there on wards we are not receiving the ACKs (Verified in GCP console). But the message process is going on in background. And we saw couple of duplicate messages as well. In our use case to process a single message it takes around 40 secs to 1 min. Ack deadline has been configured to 10 mins while creating the subscription.
Flow control configured with 20L.
ExecutorProvider configured with 3.
public void runSubsciber() throws Exception {
Subscriber subscriber = null;
MessageReceiver receiver = new MessageReceiver() {
public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
messageProcessor.processMessage(message.getData().toStringUtf8());
consumer.ack();
}
};
try {
FlowControlSettings flowControlSettings =
FlowControlSettings.newBuilder()
.setMaxOutstandingElementCount(20L)
.build();
ExecutorProvider executorProvider =
InstantiatingExecutorProvider.newBuilder().setExecutorThreadCount(3).build();
projectId=ServiceOptions.getDefaultProjectId();
ProjectSubscriptionName subscriptionName = ProjectSubscriptionName.of(projectId, subId);
subscriber = Subscriber.newBuilder(subscriptionName, receiver)
.setExecutorProvider(executorProvider)
.setFlowControlSettings(flowControlSettings)
.build();
subscriber.addListener(new SubscriberListener(), MoreExecutors.directExecutor());
subscriber.startAsync().awaitRunning();
} catch (Exception e) {
throw new Exception(e);
} finally {
if (subscriber != null) {
//subscriber.stopAsync();
}
}
}
Please help us out, Thanks in advance.

How to know who received a message in a MUC room

For my thesis, I am using Smack to log a XMPP network that uses the MUC module.
Another software is currently sending IoT sensor data into different MUC rooms.
I'd like to know for every message sent into a MUC room, which users were in that room at the time of the message. Is this possible? I could use a messageListener to every muc room, however the listener only receives a message as an argument. Therefore I could not know who is logged into the room inside the listener method.
you can get all muc message in StanzaListener in xmpp. Please follow few steps to done this
Step 1. Declare as a global variables
ChatManagerListener chatListener;
Chat chat;
StanzaListener packetListener;
Step 2. Use this code in oncreate or in fragment
Note: Make sure you have connected with chat server.
packetListener = new StanzaListener() {
#Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException, InterruptedException {
if (packet instanceof Message) {
final Message message = (Message) packet;
}
}
};
XMPP.getInstance().getConnection(acitiviy)).addAsyncStanzaListener(stanzaListener, null);
ServiceDiscoveryManager sdm = ServiceDiscoveryManager
.getInstanceFor(XMPP.getInstance().getConnection(acitiviy)));
sdm.addFeature("jabber.org/protocol/si");
sdm.addFeature("http://jabber.org/protocol/si");
sdm.addFeature("http://jabber.org/protocol/disco#info");
sdm.addFeature("jabber:iq:privacy");
Step 3. Methods for one to one chat purposer
void sendMessage(String message) {
if (chat != null) {
try {
chat.sendMessage(message);
Message msg = new Message();
msg.setTo(JidCreate.bareFrom(jid));
msg.setFrom(XMPP.getInstance().getConnection(acitiviy)
.getUser());
ChatStateExtension ext = new ChatStateExtension(
ChatState.paused);
msg.addExtension(ext);
lastComposing = System.currentTimeMillis();
chat.sendMessage(msg);
} catch (SmackException.NotConnectedException e) {
} catch (Exception e) {
}
}
}
Step 4. On destroy
XMPP.getInstance().getConnection(acitiviy)).removeAsyncStanzaListener(stanzaListener);
Hope this will help you and if you want more information take a look from here. Thankyou
Nothing prervents you from calling Multi UserCaht.getParticipants() from within the listener. But be warned: If your goal is to determine the other receivers of receivers, then this approach is fragile. I also suggest to think about using PubSub instead of MUC for your IoT use case.

smack receive message in muc using 4.1.0 rc1

Can anybody tell me how to receive message in muc using Smack 4.1.0 rc1?
I am able to send message using below code.
Message message = new Message();
message.setType(Message.Type.groupchat);
message.setBody(strMessage);
message.setTo(roomJid);
multiUserChat.sendMessage(message);
I am using below code but not able to get the message.
multiUserChat = multiUserChatManager.getMultiUserChat(roomJid);
multiUserChat.addMessageListener(new MessageListener() {
#Override
public void processMessage(Message message) {
Log.i(Constant.TAG, "processMessage");
}
});
My debugging is on and i can see that app is receiving message(D/SMACK( 6098): RECV (1):
) but listener is not getting called
Use MultiUserChat.addMessageListener(MessageListener).
send presence / join to muc before adding message listener to the muc.
then you will get muc message into the listener.
without sending presence or join to the muc, you can not get the message into the listener but you can see in the logcat.
I'm using stanza listener and able to receive MUC messages.
final StanzaListener stanzaListener = new StanzaListener() {
#Override
public void processStanza(Stanza packet) throws SmackException.NotConnectedException, InterruptedException { .. }
xmppConnection.addAsyncStanzaListener(stanzaListener, StanzaTypeFilter.MESSAGE);

Duplicate message received in XMPP Multi User Conference Room

When device1 is sending the message to the conference room "del#conference.jabber.org"
the message is dispalyed in the chat list as well as a duplicated message is also displayed that is being send by the conference room "del#conference.jabber.org". I'm stuck, why i'm getting duplicate message.
public void setConnection(XMPPConnection connection) {
this.connection = connection;
if (connection != null) {
PacketFilter filter = new MessageTypeFilter(Message.Type.groupchat);
connection.addPacketListener(new PacketListener() {
#Override
public void processPacket(Packet packet) {
Message message = (Message) packet;
if (message.getBody() != null) {
String fromName = StringUtils.parseBareAddress(message.getFrom());
String[] parts = fromName.split("#");
String from = parts[0].trim();
messages.add(from + ":");
messages.add(message.getBody());
// Add the incoming message to the list view
mHandler.post(new Runnable() {
public void run() {
setListAdapter();
}
});
}
}
}, filter);
}
}
The send message is on button click, which is as follows
Button send = (Button) this.findViewById(R.id.sendBtn);
send.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Message mg = muc.createMessage();
String text = textMessage.getText().toString();
mg.setBody(text);
Log.i("XMPPChatDemoActivity ", "Sending text ");
if (connection != null) {
connection.sendPacket(mg);
messages.add("Me :");
messages.add(text);
setListAdapter();
}
textMessage.setText("");
}
});
and this is what i have written to connect the conference room
muc = new MultiUserChat(connection, "del#conference.jabber.org");
muc.join("alias name","password");
output what i'm getting when sending message
me: hello
del: hello
what i want i no duplicate message when i send the message i.e
me: hello
When you're in a MUC room you receive copies of all the messages, including your own.
http://xmpp.org/extensions/xep-0045.html#message - "and reflect the message out to the full JID of each occupant."
So for MUCs (not for direct messages) you will get a duplicate if you log both on send and on receive (assuming you have sufficient access to post, etc.). Your options are, largely, either to not log it on send (which is the option most clients go for) or to attempt to do smart message matching to detect when you receive your own message and elide it. The former option ensures that everyone sees a consistent view of message ordering, which some people find very useful.
Maybe your chat server sent your message to you also?
So you add one message manually in onClickListener and then the same message received from server.
I think, it will be right not to add messages from onClickListener - add only those that server sends.

Get pending messages from a Chat

I am developing a chat using quickblox but I am having some problems when I open a new chat. Suddenly I received all the messages that others users sends to me when I was desconnected. The problem is that when I start a chat with user A, I receive the chats from users B, C, D.. in user A chat room.
I have find the way to only show the A users. But the problem is that the server has already sent to me the "disconnected" messages, so when I start a chat to B I do not receive any text because the message that the user B sent to me has been delivered (and ommitted) while I was chating with user A.
How can I do to receive the pending messages (kind of history) or to just retreive the message of the chat I am logged in?
A piece of my code:
// Create Connection.
Connection.DEBUG_ENABLED = true;
config = new ConnectionConfiguration(CHAT_SERVER);
connection = new XMPPConnection(config);
try {
connection.connect();
connection.login(chatLogin, password);
// Create Chat Manager.
chatManager = connection.getChatManager();
// Create Chat.
chat = chatManager.createChat(friendLogin, null);
// // Set listener for outcoming messages.
// chatManager.addChatListener(chatManagerListener);
// Accept only messages from
String from_messages = Integer.toString(receiver_chat_id);
PacketFilter filter = new AndFilter(new PacketTypeFilter(Message.class),
new FromContainsFilter(from_messages+"-3758#chat.quickblox.com"));
// Collect these messages
PacketCollector collector = connection.createPacketCollector(filter);
Packet packet = collector.pollResult();
PacketListener myListener = new PacketListener() {
public void processPacket(Packet packet) {
if (packet instanceof Message) {
Message msg = (Message) packet;
if(msg!=null){
// Process message
System.out.println("Rebem missatge: " +msg.getBody());
}
}
}
};
// Register the listener.
connection.addPacketListener(myListener, filter);
// Set listener for detect Receiver Status
if (connection.isConnected()){
roster = connection.getRoster();
roster.addRosterListener(new RosterListener() {
public void entriesDeleted(Collection<String> addresses) {}
public void entriesUpdated(Collection<String> addresses) {}
public void presenceChanged(Presence presence) {}
public void entriesAdded(Collection<String> arg0) {}
});
}
Make a arraylist and store the receiving offline messages into that array-list. you could add a code in your processPacket(Packet packet) function to add incoming messages to the array-list. or you could use Multimaps(Google Guava) to store all the incoming messages with the key. and when you open the activity that displays the messages from the certain person you could match the name of that person with the key(stored in multimap) and displays the message of that certain person. And the better option is to store all the incomming and outgoing message chat with the certain person so that you could show all the previous chat then you open up the activity.