Not logged in. · Lost password · Register
Forum: MatriX and XmppDotNet RSS
Avatar
claytoneu #1
Member since Sep 2011 · 5 posts
Group memberships: Members
Show profile · Link to this post
Subject: Is it possible for a component to subscribe to user presence?
For some context, I'm using ejabberd as my XMPP server with a MySQL backend.

For most functions, ejabberd has modules that persist everything to the database, but for some reason or another, there is no mod that will store user presence in the database.

As a workaround, my plan is to have a component subscribe to user presence and have the component handle the persistence of user presence in the database.

Is there a way for a component to subscribe to a user presence? I can see in the XMPP Component RFC that the presence tag is valid for a component, but I'm not sure to which jid the presence notifications will be sent to once I've established a presence subscription from the component to the user.
Avatar
Alex #2
Member since Feb 2003 · 4449 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
yes this should work. When your users are subscribed to the component Jid then the component gets the presence of all the subscribed users and can store it. I have done this also in combination with ejabberd before and it worked well. But you can achieve the same when you write a simple bot.

Here is also an interesting blog post from Jack Moffitt about this topic:
http://metajack.wordpress.com/2008/08/04/thoughts-on-scala…

Alex
This post was edited on 2011-12-15, 19:39 by Alex.
Avatar
claytoneu #3
Member since Sep 2011 · 5 posts
Group memberships: Members
Show profile · Link to this post
Thanks Alex!

My component is now subscribed to user presence and can now successfully receive online presence packets, but it doesn't receive offline packets.

I have handlers attached to presence like so:

public Component()
{
    OnPresence += new EventHandler<PresenceEventArgs>( Component_OnPresence );
}

void Component_OnPresence( object sender, PresenceEventArgs e )
{
    Logger.Log( "RECEIVE", e.ToString() );
}

When a user logs on, I get the expected presence packet:

[12/16/2011 12:18 PM] RECEIVE:
<presence from="user@test.com" to="user@component.test.com" xmlns="jabber:component:accept" />

But when the user logs off, the component doesn't get the offline packet. Other clients who are subscribed to that user receive the offline packet properly:

<presence to="user@test.com" from="otheruser@test.com" type="unavailable"/>

I'm not quite sure why this happens. As far as I can tell, the component should be receiving something like:
<presence to="otheruser@component.test.com" from="otheruser@test.com" type="unavailable"/>

Does ejabberd think that the unavailable packet is addressed to the sender and so it doesn't bother sending it? That would be odd considering online presence works that way.
Avatar
Alex #4
Member since Feb 2003 · 4449 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
what happens when you change the presence of a user to xa, away, dnd or chat? Do you get this presence?
When you get no unavailable presence this looks to me like server problem.

Your online presence also includes no resource, have you changed the Xml output?

Alex
Avatar
Alex #5
Member since Feb 2003 · 4449 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
here is another good article on this topic:
http://www.process-one.net/en/blogs/article/scalable_xmpp_…

Alex
Avatar
claytoneu #6
Member since Sep 2011 · 5 posts
Group memberships: Members
Show profile · Link to this post
Ah! I got it!

It turns out that the presence packets that Strophe was sending to the component were under the jabber:client namespace like so:

<presence from=?"user@testdomain" type=?"unavailable" xmlns=?"jabber:?client">?</presence>?

But since I'm sending this packet to a component, the xmlns that ejabberd is expecting is "jabber:component:accept". The presence packet above is then discarded by ejabberd and never gets to the component.

In the end, there are 2 important differences between regular presence packets and component presence packets in ejabberd:
- the namespace MUST be "jabber:component:accept"
- there MUST be an id attribute in the packet

<presence from="user@testdomain/resource" to="component.testdomain" type="unavailable" id="test-1" xmlns="jabber:component:accept" />

Thanks for the help, Alex!
Avatar
Alex #7
Member since Feb 2003 · 4449 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
All stanzas in a component must be in the jabber:component:accept namespace.
All stanzas in a client must be in the jabber:client namespace.

If they are not than namespace aware software will normally ignore them. MatriX is also namespace aware.

But its the job of the server to rewrite the namespaces.

So when a server gets a presence from a client then the presence is in the jabber:client namespace. When the sever has to forward this presence to a component it must rewrite it. if it doesn't then this is a server bug.

Alex
Avatar
Alex #8
Member since Feb 2003 · 4449 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
in MatriX you have the

  • Iq,
  • Presence
  • Message

classes 3 times in different namespaces for server, client and component.

Alex
Close Smaller – Larger + Reply to this post:
Verification code: VeriCode Please enter the word from the image into the text field below. (Type the letters only, lower case is okay.)
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Special characters: