PDA

View Full Version : How do I ask a Jabber server for a user's presence (ideally with PHP)?


X1alpha
06-22-2008, 10:31 PM
Hi everyone,

I'm looking for a way to display my Jabber online status on my website. Or on any website, for that matter. I've got my account at jabber.org.

I'd like to do it with a PHP script but have two restrictions. One is that I don't want to use a PHP bot (i.e. a script that runs in a permanent while loop); the second one is that I don't want to use another Jabber account besides the one I already have. I'm hoping for a solution as simple as possible. Like, "Hi, jabber.org. Can you please tell me so-and-so's online status? Ah, the user's offline. Thank you very much." Only in PHP :) You get the gist.

I googled for ways to achieve this and found several options. However, one way or the other they all failed due to my wish to neither use a bot nor a second Jabber account. Here's what I've found. Edgar Jabber Bot
Formerly maintained at edgar.netflint.net, now e.g. available from jabberes.org (http://www.jabberes.org/) as the Edgar 0.2.1 tar bz2 archive (http://www.jabberes.org/files/download/edgar-jabberes.tar.bz2).
Edgar is apparently capable of displaying users' online status on a page but the script runs permanently. Also, Edgar need its own Jabber account. I don't want that.


Jean-Marc Liotier's Jabber Presence Indicator
Introduced in a blog post here (http://serendipity.ruwenzori.net/index.php/2006/02/27/jabber-presence-indicator-in-a-web-page), downloadable here (http://www.ruwenzori.net/code/presence/) and demonstrated live here (http://jim.liotier.org/presence.php).
Remarkably simple but the script uses a second Jabber account. On a side note, this one's rather slow. It takes about five seconds to load Jean-Marc's presence indicator. I'm not sure though what causes the wait.I've also found fully-fledged PHP Jabber clients Florian Schmitz' class.jabber2.php
Part of his work at flyspray.org (http://www.flyspray.org/) with an example here (http://www.flyspray.org/class.jabber2.php) and a download link to the class itself in Flyspray's Subversion repository here (https://flyspray.svn.sourceforge.net/svnroot/flyspray/trunk/includes/class.jabber2.php).


Carlo Zottmann's original Class.Jabber.PHP from 2003
Formlerly maintained at cjphp.netflint.net, now downloadable e.g. from the script's Softpedia page (http://webscripts.softpedia.com/script/PHP-Clases/Class-Jabber-PHP-11820.html).


Steve Blinch's PHP Jabber Client
Maintained on Steve's page blitzaffe.com (http://code.blitzaffe.com/), namely here (http://code.blitzaffe.com/pages/phpclasses/files/php_jabber_client_52-11).


Nathan Fritz' XMPPHP
A project Nathan picked up from the original Class.Jabber.PHP. He maintains it on the project's Google Code page (http://code.google.com/p/xmpphp/).With these libraries, classes and scripts I didn't find a solution that fit my needs.

I'm still looking for a simple way (preferably with PHP) to ask the jabber.org server for my JabberID's presence. Only that, nothing more. Do you know of such a solution?

I'd gladly accept any hints and suggestions you can provide.



Greetings,

Sven

Jehan
06-23-2008, 10:30 AM
Why what you ask is apparently impossible (at least for the second account part): for security reason, you cannot ask a server who is online or not, unless having been authorized to do so! And how are you authorized? Through another account and the feature of roster acceptance! This is why another account is needed because you need this one to be accepted in your roster in order to know when your real account is on.

Yet I can see another possibility maybe: if the script connects with your own account, he probably can know all the resources connected. If it is lonely, then it considers you are not online. But if other resources are on, then it will consider you as online. I will see nevertheless at least one big drawback of such method: if ever you have offline messages awaiting for you and the script connects on your behalf: it will receive and discards your messages which you will never be aware of!

And about the permanent loop issue. I would see at least one reason why a non-permanent bot is slow: each time someone calls the page, it will have to do all the necessary connection steps before getting information about you being online or not: connection, authentication, resource binding and finally session establishment! If the bot is already connected, it just processes presence information on the live and when someone queries your page, the information is already known, so the display is instantaneous (I don't know if the bot you mentionned works this way, but I would say this would be a pretty efficient method).

X1alpha
06-23-2008, 02:24 PM
Thanks for explaining these particularities. I actually wasn't aware that you can't ask for a user's presence anonymously and that you instead have to be authorized to do so. That explains why all PHP scripts I've found rely on a second account to do their job. And why apparently nobody has ever written a script that works without the second account :)

Connecting the script from another resource and potentially missing offline messages doesn't sound all that great to me. Before I risk that I'd rather use a second account now that I know that it'll be necessary.

As for the bot and the instant availability of my online status, I understand the argument. However, I don't want to have to worry about a script that can run wild on the server. Ideally I'd need shell access to the machine to monitor PHP for any funny moves. I don't have shell access. Well, technically I could maybe use a pseudo shell like Martin Geisler's PHP Shell (http://phpshell.sourceforge.net/). I do have it installed but I like to use it for very simple shell tasks. If I used a bot it'd have to be executed from my browser and contain something like ignore_user_abort(true) and set_time_limit(0) so that the script could run no matter if the browser window was still open or not. I'd effectively have no clue what the bot was doing. I wouldn't want that.

Now that I know about the need for a second account I'll look into this solution again. My best bet is the second account and one of the above scripts and libraries.

Thanks for your input so far, Jehan.

Greetings,

Sven

Sublime Porte
06-23-2008, 08:31 PM
Actually this should be fairly simple. Whenever you login with a new resource, a presence is sent from that resource to your other resources (from what I remember). Therefore if you just create a PHP script that connects with your existing jid, it should get a presence stanza from you if you're online. The PHP script can then display some graphic/message to say you're online, if it doesn't get the presence within a few seconds can quit and display you as offline.

Jehan
06-23-2008, 11:11 PM
This is indeed what I was proposing. But I also raised the drawback of the eventuality of loosing messages whether your bot resource only is connected and receiving messages on your behalf. Unless there is a possibility for a resource to aknowledge the server not sending you anything? Maybe such an option exists, but I don't remember anything like this (though I am not omniscient about XMPP anyway).

For this reason, and probably others (I am sure the fact that a bot can connect as being yourself can have other issues), I would not advice such a procedure.

X1alpha
06-23-2008, 11:18 PM
Sounds interesting, too. Though now I'm insecure about whether or not another resource would automatically catch pending offline messages if it was the only resource logged into my account.

Jehan wrote that if I'm offline the PHP script will receive pending offline messages on my behalf. When I log in later I'll never even know that there were offline messages.

Wouldn't that happen, Porte?

Greetings,

Sven

edit:
Too slow. Jehan had already answered :)

Sublime Porte
06-24-2008, 12:03 AM
Not necessarily.
The offline message retrieval only kicks into action once you send presence, and only if it's non-negative presence. I think there's a way there for you to connect, receive presence from your other resource, and then disconnect without catching your offline messages.

There's also flexible offline messaging which allows you to choose to download your offline messages, but I don't think jabber.org supports it.

X1alpha
06-24-2008, 06:48 PM
Hi, guys,

I'm going to keep you updated with my progress. After having read a post on the Flyspray forums (http://forum.flyspray.org/viewtopic.php?pid=999) that said class.jabber2.php actually worked I gave this one a try first. And it actually does work.

A solution where I log in with my own account but with a different resource seems too advanced for my skills so I went with a second account. The script now logs into the second account and successfully displays my online status. To get a speed comparison I configured Jean-Marc Liotier's presence indicator, too. Both scripts work. However, both scripts take about five seconds to display the result of me being either offline or online. Looks like this is just how long it takes when you initially log into an account.

Plain and simple, having this on-demand script cause a delay of fives seconds is too long for me to consider it as a permanent solution. Even if I store the online status in a database such a script will still cause a lag after another five or ten minutes when the saved value has expired and it queries my status again.

The more I think about it the more the idea of a bot grows on me. I'll think this over.

Greetings,

Sven
//edit 2008-08-18:
Up until today you could find links to sample implementations of a presence indicator here. I've now completed the update for my website that I was working on. I've removed the exmaples and instead present you with the live version of a presence indicator: My website seneve.de (http://www.seneve.de/) now indicates my presence in the top left corner of each page. See this post (http://www.jabberforum.org/showthread.php?p=2621#post2621) for more details.

Jehan
06-24-2008, 08:13 PM
If the script is separated from the web server, hence the display (and for instance runs every 10 minutes as you suggest), I don't see why it would cause a lag on your website!.. unless your server is an antic slow machine and any small job on it slow down everything else!

Here you have a lag because you wait for the script to begin and end before getting any display. But if you only query the db, and separately the script feed this db, you will never get the lag of the script, even if it runs in the same time.

Anyway for the logging time, yes it looks normal, though what I try on your webpage seems lower than 5 seconds. But it is still far too slow if the visitor has to wait even 2 seconds every page he visits!

For information, I am writing a program which needs to connect to a pubsub service. The is a time (once, at the configuration of the plugin), where it needs to log, check the existence of 3 nodes, create them (and all parents) if they don't exist and unlog.
I have just made a test to see its speed. It takes 3 seconds for doing this all. This is not too bad (though obviously it would not be good if it was for the visitor, which is not :p ).

Sublime Porte
06-25-2008, 02:16 AM
A solution where I log in with my own account but with a different resource seems too advanced for my skills so I went with a second account

Logging in with a different resource is as simple as changing the name of the resource in the php script where you set your jid. As for avoiding the downloading of offline messages, you probably just need to make sure that when the script sends presence, it sends unavailable, or invisible (both of which I think would be considered negative presence).

But if you've already created another jabber account, i guess you got it all worked out anyway.

Btw, it takes about 9 seconds for the page to load for me, but that probably says more about the speed (or lack thereof) of internet connections in Australia. But be aware not everyone will have a connection as fast as yours, and many people will get even longer delays than you do. So I think it would definitely require a dedicated bot running in the background.

Some Jabber servers actually have this functionality built in, Openfire for instance has a plugin that will allow you to display your presence via the web. Don't know of any public servers that use Openfire though.

Taeril
06-25-2008, 01:20 PM
mentioned non-negative presence is presence with non negative priority
http://www.xmpp.org/rfcs/rfc3921.html#rfc.section.5.4
what server should do with such presence is described here:
http://www.xmpp.org/specs/rfc3921.html#rules

X1alpha
06-25-2008, 04:59 PM
Very interesting read, thanks for the links! According to the memo it's easier than I thought to use my main account as the bot instead of using a separate account. I can apparently log in with a different resource and set this resource's priority to a negative value. The memo writes that "the server MUST NOT deliver the stanza to an available resource with a negative priority." Also, "if the only available resource has a negative priority, the server SHOULD handle the message as if there were no available resources."

I'm going to try it out, see how far I can get with my PHP skills and how jabber.org behaves.

As for Jehan, I didn't really clarify what I meant by lag. You're of course right with your observations that it's a mere waiting time and not actual lag :)

Sublime Porte
06-28-2008, 05:52 AM
Although this mght not be useful for you, thought I'd mention it as I just found it whilst browsing.

A Jabber server that has a "webpresence" service. I tried subscribing to it from my JID but it appears you have to have an account with them.

http://www.jabber80.com/presence.php

X1alpha
06-28-2008, 12:19 PM
Actually that was useful!

[edit 2008-08-18: up until today there was an example of the jabber80.com presence indicator linked here. I've now completed the work on the update for my website that I was working on. I've removed this example from my server and instead present you with the live presence indicator on my website seneve.de (http://www.seneve.de/). It works with jabberfr.org instead of jabber80.com. See this post (http://www.jabberforum.org/showthread.php?p=2621#post2621) for more details. Here's the former text for reference:]

Have a look at example removed. Its speed is good enough for me to include it on my website. While digging into class.jabber2.php and starting to write a bot with it I felt like reinventing the wheel. Thanks to your link I've ditched the idea of a bot for the time being. Here's what I've done now instead of writing an all new bot. I've created an account at jabber80.com and registered that account with the server's presence service. The service offers different output formats, one of them being XML. I then wrote a PHP script that tests the XML output with a regular expression. The human-readable line on the demo page is the end result. The script differentiates between offline, online, away, extended away, do not disturb, free for chat and unavailable modes.

Of course, technically this doesn't help me at all in achieving my goal because while I do have an easy-to-use and responsive presence indicator now it's just for the wrong account. That's not really an issue though. I use Miranda for instant messaging so when I start the program all protocols connect to their servers. When the jabber80 account is online you can be almost 100 % certain that my main jabber.org account is online, too. Also, I set the modes globally so when jabber80 reports me as being away I'm away with all accounts.

I'm in the process of preparing an upload for my website which will properly include this presence indicator - not just as a white page with a short note. Until then I'll leave all the demonstration pages from this thread right where they are.

Greetings,

Sven

omega
06-29-2008, 06:45 PM
You can also use a service like http://presence.jabberfr.org, which enable you to display your jabber status on any page, and it works for any domain. Sorry, the webpage is in french for the moment, but it should not be to hard to understand.

X1alpha
08-18-2008, 05:06 PM
Hi, everyone,

I'm done! I've now got a working presence indicator on my website seneve.de (http://www.seneve.de/). It displays my presence in the top left corner of each page. I'd like to thank all of you for helping me find a workable solution for a presence indicator. When I first asked about it I wasn't sure how to go about this.

Omega, I'm using jabberfr.org as you suggested. It works like a charm, it's fast and easy to use. I love it. Now initially I was going with Sublime's suggestion of jabber80.com. I had it already implemented and it was working. However, one day about two weeks ago it stopped working without a warning. I couldn't log in to my jabber80.com account anymore.

Since you, omega, had already supplied me with JabberFR as an alternative I gave that a try and was overwhelmed with its simplicity and excellent performance. Plus, there's no need for an second Jabber account; I just use my current one and add presence.jabberfr.org to my roster. Very nice! In hindsight it's a real treat that jabber80.com crapped out on me ;-)

The technical part goes like this. JabberFR supplies me with a text file that contains my presence. It reads for example "Available" or "Do not disturb". If the text file has already been requested in the last five minutes a PHP script gets the presence from my MySQL database instead of requesting it again from JabberFR. If the last request was more than five minutes ago the script asks JabberFR for the latest presence. It then puts out a text appropriate for each presence. For example if the presence reads "Available" then the text on my website becomes "I'm online". If the presence reads "Away" then the website reads "I'm away". It's fast, easy to use and visitors can't hammer the JabberFR server with requests since my own server intercepts them if they come too frequently.

I've now got what I was looking for a few weeks back and I thank you for all your help, guys!

Greetings,

Sven