Offline file transfer, presence status problem. urgent!

spark2.5.8(spark2.6.0beta2) + opends + mysql + openfire3.6.4

localhost(windowsxp): opends, mysql,openfire,spark2.5.8(userA)

vmware(windows2003) :spark2.5.8(userB)

userA,userB add each other as contact.

userA send a file to userB(offline),and in chat window userA get following message:

The user is offline. Will auto-send “xxx” when user comes back online.

Then userB log in , userA get notification that userB is online, and in userA’s contact list, userB’s status turn online(gray to green,change from offline group to friend group), but in chat window(previously opened), the userB tab keep gray,and userA get the same message

The user is offline. Will auto-send “xxx” when user comes back online.

Nothing is logged on the server and client.

so what’s wrong? can anyone help me!

thanks a lot.

Filed this as SPARK-1073.

You shouldn’t see anything in the server’s logs as file transfers usually are client-2-client and server has nothing to do with this.

Hm. It seems that this is working for me with the latest Spark version. It didnt worked for the first time somehow. But. It only tries to resend the file, but the other part fails to receive the file. So there is a problem. Though there can always be some other side effects as i cant get simple file transfer working both ways on two PCs connected via ICS. Network issue can be causing these problems too.

wroot, thank you for the response.

By the way, do you mean spark_2_6_0_beta2 resolve this problem(except for the first time). I will try it later.

Thanks in advance.

I’m using the latest version from here http://www.igniterealtime.org/community/docs/DOC-1822

But it doesnt solve the problem. Though it actually tries to resend the file, but the other part cant receive anything.

hi, i’m not true if i find the solution.

I check the source code, decompile the smack.jar(with spark 2.5.8). I find that:

org.jivesoftware.smack.PacketReader has a field: listerners

protected final Map<PacketListener, ListenerWrapper> listeners = new ConcurrentHashMap<PacketListener, ListenerWrapper>();

the listerners is used to notify all packetListener.

for example:

1,org.jivesoftware.spark.filetransfer.SparkTransferManager{

private void addPresenceListener() {
SparkManager.getConnection().addPacketListener(new PacketListener() {

public void processPacket(Packet packet) {
Presence presence = (Presence)packet;
if (presence.isAvailable()) {

}

2,org.jivesoftware.smack.Roster

PacketFilter rosterFilter = new PacketTypeFilter(RosterPacket.class);
connection.addPacketListener(new RosterPacketListener(), rosterFilter);
PacketFilter presenceFilter = new PacketTypeFilter(Presence.class);
presencePacketListener = new PresencePacketListener();
connection.addPacketListener(presencePacketListener, presenceFilter);

Because listerners use Map, not List, so it’s unordered. when spark starts up, 1 may been notified before 2. but next time, 2 may before 1.

if 1 before 2, the offline file transfer will get the message:The user is offline. Will auto-send “xxx” when user comes back online

So i change org.jivesoftware.smack.PacketReader,use a ordered Map (ConcurrentSkipListMap)

      protected final Map<PacketListener, ListenerWrapper> listeners =
        new java.util.concurrent.ConcurrentSkipListMap<PacketListener, ListenerWrapper>(new java.util.Comparator(){
         public int compare(Object o1, Object o2){
          return 1;
         }
         public boolean equals(Object obj) {
          return super.equals(obj);
         }
        });

compile, then put into smack.jar

I test this , it seem ok.

hehe, i’m not sure if this is the solution. I just want this to be helpful.
PacketReader.java.zip (7882 Bytes)

Can you please attach your patch in a DIFF (difference), not as a compiled java file?

Sorry, i don’t know how to make a patch file . And i’m not sure if it’s the solution.

I modify only org.jivesoftware.smack.PacketReader in smack.

change:

protected final Map<PacketListener, ListenerWrapper> listeners =
new ConcurrentHashMap<PacketListener, ListenerWrapper>();

to:

protected final Map<PacketListener, ListenerWrapper> listeners =
new java.util.concurrent.ConcurrentSkipListMap<PacketListener, ListenerWrapper>(new java.util.Comparator(){
public int compare(Object o1, Object o2){
return 1;
}
public boolean equals(Object obj) {
return super.equals(obj);
}
});

Hm. Smack you say. So, maybe this is not a Spark issue. Anyway, i have added a comment about your suggestion in this ticket description.