Send raw XML stanzas using SMACK

Hi,

I am kinda new to smack. I am trying to send a raw stanza using smack by overriding toXML() from message class:

**
**

** Message mess = new Message() {**

** @Override**

** public String toXML() {**

** return “my_XML_raw_presence_stanza”; //due to company privacy i cannot show the XML stanza i want to send**

** }**

};

conn.sendPacket(mess);

Unfortunately this is not working. Does any one have any idea how to send custom XML stanzas using smack?

Thanks a lot,

Paco

Hi,

I haven’t done this myself, but I have seen people in the past talk about doing it by providing a custom implementation of Packet and overriding toXML(). I thought it should have worked the same for Message too, but maybe try Packet instead in case Smack does something special with Message packets. I’m not sure what you are trying to do, but you also might look at using packet extensions or key/value properties (Both are mentioned in the JavaDoc for Packet). I have used both of those features before to embed custom data inside a standard Message packet and those worked just fine for me.

Hi Paco, what you want to look at is the PacketExtension interface. You implement the interface and add an instance of the custom PacketExtension to any Packet using the addPacketExtension method defined on Packet. Then, when the packet is eventually sent, the toXML() method is called on each packet extension that has been added in order to compose the full body of the packet with your custom XML inside. For incoming custom stanzas (or extensions), you implement a corresponding PacketExtensionProvider which is able to parse the XML and populate a PacketExtension object.

If you look at the smackx source code you will see good examples of both. If you need some pointers I’ll be happy to help!

1 Like

Deeringc: would appreciate pointers.

Paco: I can use your method to send raw packets but in that case I need to put the myself …Else you are right - doesnt work.

From my reply here: http://community.igniterealtime.org/message/205115#205115

You need to start by writing a custom PacketExtension. This just needs to provide get and set methods for any data that it represents, and an implementation of the toXML() in order to tell Smack how to create the XML string that will be sent over the wire as part of the packet. Also decide on an element name and namespace.

Next, write a custom PacketExtensionProvider. This is basically a hand written parser for the toXML() string you previously created in the PacketExtension. You get passed a PullParser that points to the first element, and you iterate over the extension pulling out the values as you go. The PacketExtensionProvider returns a PacketExtension (which is obviuously an instance of the custom sub-type you previously defined), so you can now create an instance and populate it with the values you pull out from the XML.

Now you have completed the steps for going from data to XML and from XML to data. Next we need to tell SMACK to look out for the element name and namespace of the extension, so that it knows that it is in fact able to parse it. The ProviderManager lets you register a new instance of the PacketExtensionProvider against a particular elementname & namespace pair.

So, now the final things we need to do is to see how we can actually add PacketExtensions to Packets in order to send then across the wire, and also for incoming packets, be able to detect PacketExtensions. Packet subclasses (Message, Presence, IQ) inherit the *addPacketExtension *method which allows us to simply construct a packet, an extension, and to add the extension to the packet. The packet can then be sent across the wire via the *sendPacket() *method on the XMPPConnection class. To detect incoming extensions, simply register a packet listener (with an appropriate filter) * * and use the *getPacketExtension *(which takes element name and nampespace as params) to pull out the extension. It will be null if there was no extension of that element name & namespace found.