powered by Jive Software

Lost messages when network is disconnected


#1

Hello all,

If our users lose their network connection for some reason they don’t receive any messages until they come back online.

For example :

user A and user B are both online chatting back and forth

user B disables their network connection (Openfire Admin Console still shows session presence as online because the client never disconnected gracefully)

user A sends user B a message

user B comes back online, but never receives the message

We are running Openfire 3.4.1 .

Any thoughts ?

Thanks,

Dale


#2

Do you have offline messages enabled on the server? Also that may not make a difference if the user does not disconnect properly.


#3

Yes, offline messages is enabled and works fine, as long as, like you say, they disconnect properly.


#4

Hey Dale,

Based on your description it seems like Openfire is not aware that the socket connection was lost and assumes that the client is still connected. I saw that problem happen when using a nat/router between the client and the server and for that we implemented a client timeout that will detect lost connections that for some reason the TCP layer didn’t alert the JVM (i.e. Openfire) about the connection lost. By default the idle timeout is 6 minutes. However this solution leaves a time window where packets could be “lost” as you saw in your case. The final solution would be to use ACK to confirm the reception of each packet but that would be too expensive for a not common problem. Moreover, I think that a XEP for ACK is in progress but Openfire does not implement it.

Regards,

– Gato


#5

We do have the same issue, people can write messages for a long time after a client has been disconnected, and believe that the messages are delivered. XEP for ACK is a must to use Openfire for anything else than my home network (where it of course is running)


#6

Hi

We have some problem.

I’m looking for XEp-0198 support but don’t found.

The problem.

User A connect to server, user B connect to server.

User B set airplane mode. The server things user B is connected.

User A send message to user B. The message was received by the server and send to user B.

User B is offline and the server discard the message.

The message never return.

I see the XEp-0198 but Openfire don’t support this.

How con i set the server to request message delivery and if the client don’t respond store in offline message store?

Thanks


#7

It’s funny how this thread is from 2008 and this still doesn’t work. Is there a solution?


#8

Not so funny. This is how Open Source can be often - no developers or volunteers willing to invest time into free projects, no interest, no traction. Can’t do much with that.

Now about the problem. There are a few ways to approach this. Personally i have set a system setting in Openfire (Server Settings > Client Connections > Disconnect clients after they have been idle for) to 30 seconds to make this issue appear as rarely as possible. This means that Openfire will disconnect clients that have been idle for 30 seconds and are not responding to ping requests. One can set it even lower, but it can have a side effect: clients disconnecting and reconnecting often.

This is only a workaround and there is still a chance to lose a message in this 30 or so seconds gap.

The best way to mitigate this is to implement Stream Management on the server and in the client. Openfire doesn’t have this feature yet:

[OF-446] Implement XEP-0198: Stream Management - Jive Software Open Source

I’m not 100% sure, but a client most probably has to support this too. Smack library (which Spark and some other clients are based on) has added support for this recently:

[SMACK-333] Implement XEP-0198: Stream Management - Jive Software Open Source

But Spark is still using older Smack version and it is not known when it can be updated to the latest version as this could brake some functionalities (because of many changes in Smack).

Another approach would be to implement Message Delivery Receipts in a client. This way a client would get a notification that a message hasn’t been delivered (or vice versa a notification that a message has been delivered). Again, Smack already supports this:

[SMACK-331] Add support for XEP-0184: Message Delivery Receipts - Jive Software Open Source

And the latest Spark builds are using this Smack version, but there is no GUI in Spark for this:

[SPARK-1238] Add support for XEP-0184: Message Delivery Receipts - Jive Software Open Source

I’m not aware of any client supporting this.

So, the conclusion is - no developers. If this is critical to you, i suggest to search for another open source project with more active development (like Tigase, ejabberd) or look into paid solutions.


#9

I have solved this message loss problem during network fluctuation by creating custom plugin.

My plugin intercept the message packet and add it to custom table until it receives the ACK packet for this message packet.

On successful delivery of the message receiver will send a ACK packet.


#10

Can You share this plugin? I’m also looking for this.


#11

Hi Misko,

Am intercepting the packets and adding it to custom table,

public class MessagePacketInterceptor implements PacketInterceptor {

private static final Logger LOG = LoggerFactory.getLogger(MessagePacketInterceptor.class);

private static final String INSERT_msgs = “INSERT INTO CUSTOMTABLE (packetid, messageid, username, creationDate, stanza) VALUES (?,?,?,?,?)”;

private static final String DELETE_MSG = “DELETE FROM CUSTOMTABLE WHERE packetid = ?”;

/* Method intercepts the packet. If it is message store it in server database.

  • If the package is ACK from client delete the message from server database.

*/

@Override

public void interceptPacket(Packet packet, Session session, boolean incoming, boolean processed) throws PacketRejectedException {

if (packet instanceof Message && incoming && !processed) {

Message message = (Message) packet;

try {

// If the packet is for ack ignore it

isACKPacket(message); // THIS THROWS MsgSaverAckException

// Store message in to OpenFire database

storeMessage(message);

} catch (MsgSaverAckException e) {

// Delete the message from table based on the acknowledgment

deleteMsg(message);

// @PacketRejectedException is thrown to avoid sending back the ACK package.

throw new PacketRejectedException();

} catch (MsgSaverException e) {

LOG.error("" , e.getMessage());

}

}

}


#12

I’m also troubled with lost messages when network is disconnected,

so I want to use your custom plugin.

However I cannot write source cord by myself.

Could you share package of your custom plugin not a part?

Best regards,

Udhayakumar


#13

i think it is too late, but the answer is worth it. i fixed the problem by enabling ping, you can enable it in the server settings, make it every 10 seconds or 5 seconds. depending on what you want. it will automatically disconnect the user if the user lost internet connection. if you want auto reconnect the user when he gets back the connection then enable re connection by adding re connection listener. However, a plugin should be made for this so the person will not lose messages.


#14

I have also enable ping in server as well as client side. and server automatically disconnect the user.The problem is that in between 10 sec all messages Lost and message not store in offline table.