Cant get PacketExtension object from pubsub#event

No matter how I try, it seems I get can’t the MediaRecordingExtension which implements PacketExtension created by my MediaRecordingProvider. I can see it’s running through the Provider and its parser, but I can’t figure out how to get MediaRecordingExtension back after that. I was hoping someone could give me a little guidance about how to achive this.


**Here's how I connect: **

// Add custom extension provider

ProviderManager.getInstance().addExtensionProvider(

MediaRecordingExtension.elementName,

MediaRecordingExtension.namespace,

new* MediaRecordingProvider()*);

// Config our connection

ConnectionConfiguration config = new ConnectionConfiguration(mServer, mPort);

config.setSASLAuthenticationEnabled(true);

connection = new XMPPConnection(config);

// Connect to device

connection.connect();

connection.addConnectionListener(connectionListener);

connection.addPacketListener(new PacketListener(){

@Override

public void processPacket(Packet p) {

PacketExtension pe = p.getExtension(MediaRecordingExtension.namespace);

if (pe instanceof MediaRecordingExtension){

MediaRecordingExtension e = (MediaRecordingExtension) pe;

System.out.println(e.getId());

} else {

System.out.println("It is NOT an instance of MediaRecordingExtension");

}

}

}, new PacketTypeFilter(Message.class));

**Here's how I subscribe (which really kinda sucks): **

subscribeNode("urn:fake-com:fake-alert:remote-event:device:media:recording:motio n-detected");

private void subscribeNode(final String node){

//Build the subscribe request for the current user.

IQ iqPacket = new IQ()

{

public String getChildElementXML()

{

                            return "" +

"" +

"" +

"" +

"" +

                                                                      "[http://jabber.org/protocol/pubsub#subscribe_options](http://jabber.org/protocol/pubsub#subscribe_options)" +

"" +

""+

"items" +

""+

"" +

""+

"";

}

};

iqPacket.setType(IQ.Type.SET);

iqPacket.setFrom(connection.getUser());

iqPacket.setTo(mServerJid);

connection.sendPacket(iqPacket);

}

**Here is the event response from the event I subscribed too above after I got a successful 'subscribed' response from the above subscription request:**















/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAB=









Once I receive this subscribed event, I can see that the packet travels through the *MediaRecordingProvider() *and is parsed into a MediaRecordingExtension there properly, but after that, the PacketListener processPacket method above results in: “It is NOT an instance of MediaRecordingExtension”, and I can’t figure out why. I’m not sure how to get my MediaRecordingExtension back once its parsed.

Also, I hate the way I have to subscribe for this event. I really don’t like the custom XML there to create this and am open to better ideas for this.

Can someone point me in the right direction? I’m interested in any input anyone might have.

Thank you,
Gary Tessman

You are making it harder than it needs to be since you can do this through the existing API. Call *node.addItemEventListener() *(before you subscribe). The payload from the PayloadItem will be what you are looking for.

An example is in the test file TestEvents. Look up the commented out method testSendAndReceiveCarPayload() as it does exactly the same thing.

Thank you very much for your reply.

After about 2 weeks on this pub/sub stuff, it almost seems easier how I was trying to do it - which almost worked. At least I could see it going through my provider and extension. I am only a xmpp client here. PubSubManager.getNode() for the ItemEventListener always seems to send data to the server, which I dont think is what I want yet…? I also don’t want queue’d message as the example shows. I need this to be a live event handler.

As suggested, I tried to setup itemEventListener, but this is the results.

PubSubManager pubsubMgr = new PubSubManager(connection, mServerJid);

Node n = null;

try { // Is this supposed to match my itemsNode/Extension or my subscription node?? Either way,

// both fail with the same results.

n = pubsubMgr.getNode(“urn:fake-com:fake-alert:remote-event:device:media:recording” );

} catch (XMPPException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

n.addItemEventListener(new ItemEventListener() {

@Override

public void handlePublishedItems(ItemPublishEvent items) {

logger.debug(“handlePublishedItems()!”);

}

});

Sent this to server:

Got this back:

Results in this in the logs:

item-not-found(-1)

at org.jivesoftware.smackx.pubsub.packet.SyncPacketSend.getReply(SyncPacketSend.ja va:53)

at org.jivesoftware.smackx.pubsub.packet.SyncPacketSend.getReply(SyncPacketSend.ja va:61)

at org.jivesoftware.smackx.pubsub.PubSubManager.getNode(PubSubManager.java:163)

Why does it need to send anything to the server at this point? I’m not subscribing yet. So how do I just setup an itemEventListener without sending data to the server just yet?

Because getNode() checks with the server to find out if the node exists. If it doesn’t exist, then getNode() returns null (which is the error you are currently seeing). Typically if getNode() returns null, you would call createNode to create it before carrying on. This seems reasonable since there is no point to attempt further operations if the node doesn’t exist.

The example I pointed out doesn’t use queued messages, the getItems() method is for that. The ItemEventListener is for live events only (with the exception that the last published item to a node is typically sent to a new subscriber).

You can certainly code it all yourself, but in the end it will only accomplish the same thing that the API already does. The handler method will deliver your custom packets to you via the listener. It is simply a more specific version of the PacketListener, tailored specifically for pubsub.

FYI, your original packet listener didn’t work because you were checking for your extension as the packet extension. It isn’t, it is embedded within the packet extension which is a pubsub items extension. You will have to check for your custom xml within this packet. But as I said, the API already does this for you.

Thank you kindly again for your reply.

Because the server (which isn’t something I have control over) responds that the node doesn’t exist - I can’t subscribe to it? I can’t create a node on the server because I don’t own that code. Or can I?

However, I do know the the server subscription exists, this is the typical response to me subscribing. I subscribe to this node and get this response.

These are the events I will receive once subscribed:

<event xmlns='[http://jabber.org/protocol/pubsub#event](http://jabber.org/protocol/pubsub#event)'>

<items node='urn:fake-com:fake-alert:remote-event:device:media:recording:ended’>

<*MediaRecordingEnded *xmlns=‘urn:fake-com:fake-alert:remote-event:device:media:recording’>

/9j/4AAQS…kkD//2Q==

The urn:fake-com:fake-alert:remote-event:device:media:recording:ended is items node from the event response. However, my extension is MediaRecordingEndedExtension xmlns=’**urn:fake-com:fake-alert:remote-event:device:media:recording’ because its a subnode in the event items message. But I subscribe to urn:fake-com:fake-alert:remote-event:device:media:recording:motion-detected **

** **How can I “create” a node on the server (which I dont have code too) to using existing API’s as you suggested with createNode(“urn:fake-com:fake-alert:remote-event:device:media:recording:motion-detected") , or enable the ItemEventListener on some node, if I can’t get a succesful response from “getNode(”**urn:fake-com:fake-alert:remote-event:device:media:recording:motion-detected”) **or createNode ? I’d still like to use the itemEventListener, or existing API’s instead of doing it the hard way.

Am I just missing something here? Should I be using the items namespace, or my item namespace here in the create or getNode methods to use this itemEventListener on this?

Thank you!

YES! I got it working just as you suggested.

I had a few things going on.

1.) I had to pass a resource at login (I suspect this is what caused me many problems)

2.) I added “ConnectionConfiguration.setSendPresence(false);”

3.) I set manually set my presence so I could pass status text as “Available”

4.) I had a bug in my Provider which was returning a couple fields as “null”

5.) I finally figured out that the PubSubManager.createNode needed me to use my clientJid (not the server I was connecting to) when I created the PubSubManager.

I am still not sure if I need to use this ExtensionProvider, but I will figure it out:

ProviderManager.getInstance().addExtensionProvider(

MediaRecordingExtension.elementName,

MediaRecordingExtension.namespace,

new MediaRecordingProvider());

At least now I can pubsub with the PubSubManager and see the handlePublishedItems method being called! I’m very excited about it :slight_smile:

Thank you very much for your help Robin! You definately helped me and guided me in the right direction and suggested I use the existing API to do it the right way - I feel better about it now.

Thanks again!
~Gary

I am happy for you.

You will want to use your extension provider. This means that in your handler, you will automatically get a list of PayloadItem instances. Otherwise you will get a SimplePayloadItem which basically just gives you access to the text of the payload instead of a context specific object i.e. your MediaRecordingExtension.