powered by Jive Software

How to modify packets to be sent

Hi there,

i have a question regarding filtering and modifying packets to be sent. Here is my SIMPLE scenario. A user types in some message, such as “hello”. Then a sparkplug intercepts it and append “world” before it is sent. So the receiver receives “hello world”. So far, I’ve tried the following:

  1. chatManager.addMessageFilter, where the MessageFilter has two methods “filterOutgoing” and “filterIncoming”

  2. xmppConnection.addPacketWriterLIstener

  3. xmppConnection.addPacketWriterInterceptor

However, they all behave a little bit randomly, i.e. they don’t modify all messages.

I think the reason is somehow along the line where the filters (1) and listeners (2) are asynchronous with the sending thread. So if the modifying thread is faster than the sending one, then everything is good; otherwise, we still get unmodified message.

The PacketIntercepor (3) is supposed to be synchronous, but it still cannot do what I want. I’m copying the javadoc of its method here.

====

Process the packet that is about to be sent to the server. The intercepted packet can be modified by the interceptor.

Interceptors are invoked using the same thread that requested the packet to be sent, so it’s very important that implementations of this method not block for any extended period of time.

====

So could some one please tell me how to do this simple job in Spark/Smack/Sparkplug at all? I asked a similar question a week ago (http://www.igniterealtime.org/community/thread/30329) but didn’t get an answer. Hope it’s different this time. Thanks a lot.

I found the reason!!!

It’s not about threading. I was misled by some of the documents. I followed up the source code of spark and smack. The real “culprit” is:

**org.jivesoftware.smack.packet.MessageEverytime you call message.setBody(“body string”), it add this body to its internal hashset, instead of replacing it. Then depending which one appears first in the hashset, you might get either one. The solution is to get the original body first (for processing), then remove it with message.removeBody((String)null). Casting null to String is because removeBody is overloaded. Then you call message.setBody(newbody) I think this is either a bug or a poor documentation. Anyway, I’m very glad I found the reason and hope this is useful for those who may have the same problem as I.