• Winking Gwyn
  • Categories

  • Feeling generous today? Any money received will support the continued web hosting of this blog. Donate towards my web hosting bill!
  • Gwyneth Llewelyn is offline in Second Life.
  • Pages

  • Meta

  • Blog Rank: 124,475
  • Status Updates

    • Allow group ownership of private islands (multiple owners paying the cost for the private island together) http://ping.fm/gXJ6z
      2 days ago
    • [Blog] SL 2.0 Beta still running too slowly on your Mac? No worries!: If, like me, you're not the kind of person th... http://ping.fm/Y0gYX
      10 days ago
    • [Blog] The new possibilities of the XStreetSL "money API"?: I have to confess, I'm quite excited by the tremendous ... http://ping.fm/arSLj
      10 days ago
    • Yay, XStreetSL got some properly working CSS :) No more horizontal scroll bars... it's fluid now :)
      11 days ago
    • [Blog] Where is There?: Nowhere! http://ping.fm/khsS6
      12 days ago
    • Not There Any More: There.com shuts down its virtual world: http://ping.fm/wTCnW
      12 days ago
    • New simulator server software (1.36.4) seems to fix the problem with Estate Bans that didn't work: http://ping.fm/6Zr1W
      12 days ago
    • Call for speakers for the B2P 2010 Spring Conference "Leadership in Business" in #SL, promoted by @B2PBetaTech: http://ping.fm/DhXZT
      13 days ago
    • What a great idea: better integration of shared media and the UI on HUDs (adding transparency): http://ping.fm/FwJL6
      17 days ago
    • Our own @Doubledown_InSL hits CNN: http://ping.fm/W0aEK Congrats, DD! (Thanks for the link, @TrudyTakacs!)
      18 days ago
  • PostRank Topblogs 2009 - #16 in Virtual Worlds
  • RSS My Other Blog

11 Aug

Figuring out your online status, revisited

Three years ago, when I was learning how to integrate Second Life with external web servers in the summer of 2004, I posted some code for figuring out your online status from a website, blog, forum, etc. The tricky bit at the time was that XML-RPC requires a ‘channel’, which is created from scratch every time you register an object to handle XML-RPC calls, but this channel changes over time as sims get rebooted, or SL gets upgraded, or the asset server goes down, etc.

XML-RPC only allows queries from outside to an in-world object (but you can return an answer); in those days, the only way to store that channel on your webserver, to make sure you knew where to send the XML-RPC messages, was to send the channel ID by email. Parsing mails on a webserver, however, is an option that most low-cost web hosting services do not give you; it’s also not trivial, and very often requires you to have mail set up correctly (also, forget doing that under a Windows server). I just sent the channel to my own email address and manually changed it on my website.

Since Linden Lab introduced llHTTPRequest(), things are much easier. Using it, you can also call a webserver from any object — so now you have a simple and easy way to inform your website that the channel ID has changed! The PHP code I had was also designed for PHP4, using an external XML-RPC library that was quite easy to use. PHP4 has been made obsolete now, so it’s time to change the code to adapt. For me, it meant finding a new XML-RPC library. PHP5 has one, PEAR has another, and a lot of those are around, but almost all are hugely complex and, in some cases, you need to install it first, which may not be an option for the low-end hosting services. By chance, I was browsing through WordPress to see what library they were using — and I found one that works well under PHP4 and 5, comes with every WordPress installation, and it’s even simpler to use than Keith Devens‘ own, who never troubled himself to upgrade his library to PHP5. So here follows the code. The first bit is the LSL script to place in your object. As you can see, it follows the same model as my 2004 code pretty closely. If your object changes XML-RPC channel by any chance, just reset it or rez it again. Note that the webserver will always store the channel ID from the last object rezzed (but all should retrieve the same information from LL’s database servers, so it’s irrelevant).

// Code by Gwyneth Llewelyn to show online status and let it
// be retrieved by external XML-RPC calls

// Global Variables
key avatar;
string avatarName;
string onlineStatus = "status unknown"; // preserve it
key onlineStatusRequest;
key webResponse;    // we send the RPC channel ID to the webserver

default
{
    state_entry()
    {
        llSetTimerEvent(60.0);  // call a timer event
                        // every 60 seconds.
        avatar = llGetOwner();
        avatarName = llKey2Name(avatar);
        llOwnerSay("Registering with RPC server and retrieving user data from database server…");
        llOpenRemoteDataChannel()// this sets the object up to accept external XML-RPC calls
    }   

    on_rez(integer startParam)
    {
        llResetScript();
    }

    timer()
    {
        // Every 60 seconds, retrieve the online status from the SL database server
        onlineStatusRequest = llRequestAgentData(avatar, DATA_ONLINE);
        llSetText(avatarName + " is " + onlineStatus, ZERO_VECTOR, 1.0);    // set the hover text
    }

    dataserver(key queryid, string data)
    {
        // this is what SL returns to us when we call llRequestAgentData()
        if (queryid == onlineStatusRequest) // check if it’s the correct request
        {
            if (data == "1")    // online status is just 0 or 1
                onlineStatus = "online";
            else
                onlineStatus = "offline";
        }
    }

    remote_data(integer event_type, key channel, key message_id, string sender, integer idata, string sdata)
    {
        if (event_type == REMOTE_DATA_CHANNEL)
        {
            // SL has set up a channel for the XML-RPC calls
            llOwnerSay("Channel id "+(string)channel);
            llOwnerSay("Sending channel id to web server…");
            // We’ll save it, by sending it to our server
            webResponse = llHTTPRequest("http://insert.your.domain.here.tld/save-channel.php",
                        [HTTP_METHOD, "POST",
                        HTTP_MIMETYPE, "application/x-www-form-urlencoded"],
                        "channel=" + (string)channel);
        }
        if (event_type == REMOTE_DATA_REQUEST)
        {
            // This is a call made from our web site/blog asking us for the online status
            llRemoteDataReply(channel, message_id, onlineStatus, idata);
        }
    }

    http_response(key request_id, integer status, list metadata, string body)
    {
        if (request_id == webResponse)
        {
            if (status == 200)  // we’ll get a 200 OK status if the web server stored the XML-RPC channel correctly
                llOwnerSay("Channel id successfully saved");
            else llOwnerSay("Webserver error " + (string)status + ": " + body);
        }
    }
}

Now it’s time to take a look at the web-side code. The first bit is the handler for the new channel. I’ve done a quick-and-dirty thingy that simply writes to a local file. Since this is meant to be used inside things like your own hosted blogs/websites/forums, just pick a local directory that is writable and use it. For WordPress, I’m using the uploads directory and the filename I’ve picked was channels.inc. Just copy and paste the following code into a file called save-channel.php where your webserver can find it:

<?php
if ($_REQUEST[‘channel’])
{
    include(‘./wp-config.php’);
    $filename = ABSPATH . ‘wp-content/uploads/channel.inc’;
   
    $fd = fopen($filename, ‘w’);
    if (fwrite($fd, $_REQUEST[‘channel’]) === FALSE)
    {
        header("HTTP/1.0 503 Service Unavailable");
        echo "File $filename not writeable – channel not saved";
    }
    else
    {
        fclose($fd);
        header("Content-type: text/plain; charset=utf-8");
        echo "Channel " . $_REQUEST[‘channel’] . " saved.";
    }
}
else
{
    header("HTTP/1.0 405 Method Not Allowed");
    echo "No channel specified";
}
?>
 

And finally comes the last bit — adding the relevant code on your site/blog/forum to check if you’re in-world or not. This requires including class-IXR.php, which is available from Incutio. However, the WordPress guys have continued to update this XML-RPC library and have a more recent version.

<?php
include_once(ABSPATH . WPINC . ‘/class-IXR.php’);

$client = new IXR_Client(‘http://xmlrpc.secondlife.com/cgi-bin/xmlrpc.cgi’);

$payload["Channel"] = file_get_contents(ABSPATH . ‘wp-content/uploads/channel.inc’);
$payload["IntValue"] = 0;
$payload["StringValue"] = "online status";

print "I am ";
if ($client->query(‘llRemoteData’, $payload))
{
    $response = $client->getResponse();
    print $response["StringValue"] . " in Second Life.";
}
else
{
    print "having problems contacting RPC server…";
}
?>
 

Enjoy!

Related posts:

  1. Figuring out your online status in Real World
  2. Generic llSitTarget Positioning Script
  3. Finally, the blog is back online…
  4. Immersionism and Augmentationism Revisited
  5. Three Years Late… But HTML-On-A-Prim is Here!

Related posts brought to you by Yet Another Related Posts Plugin.

  • I have it install on my wordpress. So i don't really know whats up with that.
  • Ah... I wonder if you're using this script on a WordPress blog? :)

    Because if you aren't, you'll need to download <tt>class-IXR.php</tt>, install it somewhere, and rewrite the whole code to point the paths properly to it. Or, well, use any other PHP XML-RPC packages (there are a lot of them; Incutio's IXR just happens to be small, efficient, and very simple to us; these days, most installations of PHP also include XML-RPC classes, which are probably faster since they're C libraries :) ).

    Oh yes, I most definitely will use http-in as soon as it's available (hopefully still in 2009!). LL will slowly phase out XML-RPC — and not abruptly — since their own XstreetSL.com web shop uses XML-RPC profusely, and a hundred thousand people use that every day. That's a lot of code to replace!
  • On the online.php that shows your online or not i get Parse error: syntax error, unexpected T_CLASS in /home/searchi9/public_html/web3/online.php on line 2
    and on the save-channel.php is giving me
    Parse error: syntax error, unexpected '/' in /home/searchi9/public_html/web3/wp-content/uploads/save-channel.php on line 4

    And also are you going to remake this when http-in is in the main version? One of my scripter friends told me they are going to take out xml-rpc when http-in is in.
  • Kevin, which of the two PHP scripts gives that error to you?
  • Parse error: syntax error, unexpected T_VARIABLE in /home/kevinoto/public_html/online.php on line 3 I am getting this. I am not sure how to fix it. Thanks
  • Oops. You're so right! Thanks for spotting the bug!
  • Gwyneth,
    Nice job, very interesting.

    But note that in the SL script there is a little bug:
    the line [if (status = 200) // we’ll...]
    should be if (status == 200) // we’ll...]

    However, many tks for your great job!
blog comments powered by Disqus

© 2010 Gwyn’s Home | Entries (RSS) and Comments (RSS)

Powered by Wordpress, design by Web4 Sudoku, based on Pinkline by GPS Gazette