2

I'm new to XMPP and the xmpp4r library, so please forgive my noob question if this is obviously documented somewhere.

What's the most straightforward way, in a synchronous manner, to find out if a given JID is online? (so that I can call something like is_online?(jid) in an if statement)

My details:

I'm writing a Sinatra app that will attempt to send a message to a user when a particular url gets requested on the web server, but it should only try to send the message to the user if that user is currently online. Figuring out if a given JID is online is my problem.

Now, I know that if I connect and wait a few seconds for all the initial presence probe responses to come back to the Roster helper, then I can inspect any of those presences from my Roster and call #online? on them to get the correct value. But, I don't know when all of the presence updates have been sent, so there's a race condition there and sometimes calling #online? on a presence from my roster will return false if I just haven't received that presence probe response yet.

So, my current thinking is that the most straightforward way to find out if someone is online is to construct a new Presence message of type :probe and send that out to the JID that I'm interested in. Here's how I'm doing it right now:

#jabber is the result of Client::new
#email is the jid I'm interested in polling
def is_online?(jabber, email)
      online = false
      p = Presence.new
      p.set_to(email)
      p.set_from(jabber.jid)
      p.set_type(:probe)
      pres = jabber.send(p) do |returned_presence|
        online = returned_presence.nil?
      end

     return online
end

Now, this works in cases where the user is actually online, but when the user is offline, it looks like the presence probe message that comes back is being caught by some other presence_callback handler that doesn't know what to do with it, and my is_online? function never finishes returning a value.

Can anyone help me by providing a simple example is_online? function that I can call, or point me in the right direction for how I can detect when the roster is done getting all the initial presence updates before I try checking a presence for #online?

Gabe Hollombe
  • 7,847
  • 4
  • 39
  • 44
  • 1
    Why not directly send a message of type headline to the user, instead of testing before if user is online ? Let the XMPP return an error is contact is unavailable. And that's one less message. – Eric Nov 09 '09 at 07:38
  • Oops, forgot a word : "Let the XMPP *server* return an error is contact is unavailable." – Eric Nov 09 '09 at 07:43

1 Answers1

1

As it turns out, there's not a synchronous way to ask for a JID presence. You've just got to ask for what you want, then wait for your response handler to fire when the response arrives.

Gabe Hollombe
  • 7,847
  • 4
  • 39
  • 44
  • Can you post sample code for this? I've tried it with presence and with a message of type headline. Presence hangs and headline actually delivers a message to the user in the case they are online, which breaks my use case. – johnnygoodman May 12 '13 at 15:11
  • I'm sorry, @johnnygoodman, but this was so long ago now that I don't have that code handy anymore. – Gabe Hollombe May 12 '13 at 22:58