Disable auto-forward of messages in OFOFFLINE in Openfire

Hello all,

I’m looking for a param or a system to avoid Openfire “auto-forward” messages from OfOffline.

Often my users starts 2 clients and since an openfire-smack it’s embedded, they do a double connection, so I need to not lose OfOffline messages. I know Openfire does not support multiple connections (wrost, with same Resource…) so I need to “patch” OfOffline with this behaviour.

I need Openfire still store the messages but I want to retrive the list manually.

It’s that possible?

As alternative, can be good enough to avoid auto-cleaning of OFOFFLINE table (process two times ofoffline messages by client can be done without issues)

Thanx in advice

I think ofOffline messages are only sent if the user sets a presence. When I want to do quick logins, I don’t set presence.

Hi

you can disable storing and forwarding offline message from admin panel. i am attaching screen shot below hope it will help you.

Hi Daryl,

I never managed by myself Presence (my usecase it’s without roster).

So, basically, i can send an unavailable Presence and when I’m ready send an available presence?

What about unavailable Presence? Openfire does not check ofoffline messages, anything more to know? Can I join and receive messages of a groupchat, just as example?

@Hiren: I need “always store”, I just want to avoid to let Openfire autoload OfOffline messages, not avoid to store the messages Thanx anyway

I has some tests, as first step **after login **i sent a Presence.unavailable, recorded by server. Openfire retrived by itself autoforward of ofoffline messages.

What I had wrong? Any other option available? Thanx in advice

Hi Oibaf,

sorry i take it wrong way now i can understand your situation better i think.

I think you want to store the offline message but when user logins openfire delivers those message and it will delete from ofoffline table but you want to pretend them right?

you can do it after changes src code of openfire and rebuild it.

when you will look at openfire src code you wil find servermanager.java(src/java/org/jivesoftware/openfire) the code snippet i have attached below.

if (session.canFloodOfflineMessages()) {

OfflineMessageStore messageStore = server.getOfflineMessageStore();

Collection messages = messageStore.getMessages(session.getAuthToken().getUsername(), true);

for (Message message : messages) {

session.process(message);

}

}

this code will run when you are login and it will featch all offline message using “getMessages(session.getAuthToken().getUsername(), true)” and it will process after you successfully logged in.

when you look at “getMessages(session.getAuthToken().getUsername(), true)” method it is resides in (offlinemessagestore) under same directory i have mentioned above.

you will find method as below :

public Collection getMessages(String username, boolean delete) {

List messages = new ArrayList<>();

SAXReader xmlReader = null;

Connection con = null;

PreparedStatement pstmt = null;

.

.

.

}

here you can see second parameter which is passed in openfire method is true which indicates you want to delete those message after processing it if you don’t then you should pass false as second parameter so if you want those messages after processing you need to change second parameter as “false” and it will stop deleting messages from ofoffline table and you can retrive this messages second time when you logged in.

for your ref i am attaching src link from github of both classses please visit you will get clear your doubts.

Openfire/SessionManager.java at master · igniterealtime/Openfire · GitHub

Openfire/OfflineMessageStore.java at master · igniterealtime/Openfire · GitHub

There are also other way to manage those message please ping you want to know any more way to get this message.

Hope this time i got you right…

nothing wrong the way you went but openfire delivers offline message as soon as you successfully logged in so when you logged in and settting presence unavaliable openfire does the process of forwarding offline message in between so you will get all the message still you had set your presence offline.

This is a fantastic solution, thank for your time, but I can’t rebuild Openfire. I already looked for that snippet and I was unable to find a param or a condition to let Openfire pass “false” as delete or not invoke at all this method. I will try to write a plugin to force session.canFloodOfflineMessages() to return false.

I read canFloodOfflineMessages has this kind of control:

if(offlineFloodStopped || presence.getPriority() < 0) {

return false;

}

now I will check about a presence priority less than 0 or something like that.

Thank you very much

1 Like

Hi Hiren, I don’t want to open another topic about.

Looking in source code, i noticed as I mentonied 2 things:

  1. Check on Presence Priority. (if <0)

  2. An interesting comment on top of the method

/**

  • Returns true if the user requested to not receive offline messages when sending

  • an available presence. The user may send a disco request with node

  • user when he becomes online. If the user is connected from many resources then

  • if one of the sessions stopped the flooding then no session should flood the user.

  • @return true if the user requested to not receive offline messages when sending

  •     an available presence.
    

*/

public boolean isOfflineFloodStopped();

WIth smack I had some tests with no result: seems openfire ignores priority etc. Do you have any evidance?

My snippents

XmppManager

connection.connect()

connection.sendStanza( new Presence( Presence.Type.available, “Foo”, -1, Presence.Mode.xa) );

ProviderManager.removeExtensionProvider(“offline”,“http://jabber.org/protocol/offline”);

ProviderManager.removeIQProvider(“offline”,“http://jabber.org/protocol/offline”);

ServiceDiscoveryManager.getInstanceFor( connection ).removeFeature( “http://jabber.org/protocol/offline” );

ServiceDiscoveryManager.getInstanceFor( connection ).removeNodeInformationProvider( “http://jabber.org/protocol/offline” );

Hi Oblif,

Actully this commented portion suggest’s you that if you don’t want to flood offline message then you should pass iq message to Offline handler it will set offlineFloodStopped to true so that when you establish your session your method willl return false. i am explaning how does it work so don’t be confused.

Here the main method i mean the canFloodOfflineMessages method need to return false so that you can stop flooding of offline message right?

Here look at snippet:

if the marked yellow part retuns true then your method will retun false do you agree?

now we are pointing that method

this method simply return the class variable offlineFloodStopped which is bydefault false you can see it from

Openfire/LocalClientSession.java at master · igniterealtime/Openfire · GitHub

now if you want that this method should return true so that it will retun true to it’s parent method and parent method(canFloodofflineMessage) retuns false right?

now there is only one way to change this class variable which i will show you in below code snippets:

now this method is executes from only one place IQOfflineMessagesHandler

now the root cause is you need to execute this method somehow before the it is start flooding messages right?

now read the comment part once again " The user may send a disco request with node “http://jabber.org/protocol/offline” so that no offline messages are sent to the user when he becomes online."

it is suggesting that you need to sendiq packet before user becomes online it will set that flag (offlineFloodStopped)as true and you don’t get offline messages when your priorty or presence change to online.

Hope you got it…

i am attaching refernce link of all user classes

1 Openfire/LocalClientSession.java at master · igniterealtime/Openfire · GitHub

2 Openfire/IQOfflineMessagesHandler.java at master · igniterealtime/Openfire · GitHub

3 Openfire/SessionManager.java at master · igniterealtime/Openfire · GitHub

Thanx, this part was clear enough but I don’t get how to send IQ packet.

About priority: Openfire simply ignore my priority setted as “-1”. In Admin panel I check everytime that priority it’s 0. I really can’t understaind why, if I try to pass something like -129 validation in Packet.class regoulary throws the exception “priority must be between -128 +128” so the tag it’s not ignored. I think I miss something but I don’t know what.

About “The user may send a disco request with node “http://jabber.org/protocol/offline” so that no offline messages are sent to the user when he becomes online.” what I get it’s prolly that you don’t know SMACK so basically you explained me the OF’s code, **I don’t want to waste your time anymore and I thanx you again and again for your time **

I’m looking for sending this kind of IQ to Openfire with SMACK or also by writing char by char by myself.

By SMACK seems I have to use ServiceDiscoveryManager but I can’t get any result… I will try to use this tutorial, i just miss this test If I’ll obtain any result I will reply here.

http://download.igniterealtime.org/smack/docs/latest/documentation/extensions/di sco.html

// Obtain the ServiceDiscoveryManager associated with my XMPPConnection ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection); // Create a DiscoverItems with the items to publish DiscoverItems itemsToPublish = new DiscoverItems(); DiscoverItems.Item itemToPublish = new DiscoverItems.Item("pubsub.shakespeare.lit"); itemToPublish.setName("Avatar"); itemToPublish.setNode("romeo/avatar"); itemToPublish.setAction(DiscoverItems.Item.UPDATE_ACTION); itemsToPublish.addItem(itemToPublish); // Publish the new items by sending them to the server discoManager.publishItems("host", itemsToPublish);

Ok, was simple: if you use SMACK API, just disable automatic Presence while connect to the server

XmppManager.config = XMPPTCPConnectionConfiguration.builder()
.setSendPresence( false )
.setServiceName(serverName)
.setHost(server)
.setPort(port)
.build();

connection = new XMPPTCPConnection(config);

1 Like