Repost: XML-RPC Implementations
|
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
|
07-06-2004 16:44
Hello everyone! Since the last forum change knocked out the old Script Discussion forum, I think this thread deserves a resurrection. The scripters of Second Life all come from diverse programming backgrounds. Some may even have had LSL as their first programming language. With the recent addition of inbound XML-RPC, many scripters needed to whip out their non-LSL programming skills and code an external XML-RPC client to send data to the inside. The problem is, is that not everyone has those kinds of skills. This thread is created to show how XML-RPC can be implemented in as many different languages as possible, and to assist those scripters who don't have the programming skills necessesary to create an XML-RPC client in another language. Let's try and top the number of responces the old thread had!  ==Chris
|
Piprrr Godel
Code Wrangler
Join date: 25 Sep 2003
Posts: 54
|
Hit 'n run response
07-06-2004 17:05
C++ implementations might consider using Qt . Though originally designed for cross-platform applications, it has added network socket and XML support, both of which will be needed to communicate to Second Life objects via remote XML streams.
_____________________
I'm taking reality in small doses to build immunity.
|
Eddy Stryker
libsecondlife Developer
Join date: 6 Jun 2004
Posts: 353
|
Re: Hit 'n run response
07-06-2004 17:15
From: someone Originally posted by Piprrr Godel C++ implementations might consider using Qt . Though originally designed for cross-platform applications, it has added network socket and XML support, both of which will be needed to communicate to Second Life objects via remote XML streams. Or you could use a library that was meant for XML-RPC (like http://xmlrpc-c.sourceforge.net/) instead of adding a 14mb download with a 2-4 hour compile time that is only freely available on non-Windows platforms as a prerequisite to a simple RPC server. Don't get me wrong, I've been an almost exclusive QT programmer for the last year and a half, giving several presentations on it and developing commercial and open source software with QT. I love the lib to death (it's the C++ answer to Java), but there's a time and a place. And for a PHP solution I already made a thread, reference here: /54/71/17016/1.html
|
Alondria LeFay
Registered User
Join date: 2 May 2003
Posts: 725
|
07-06-2004 20:48
Here is my Perl example. Somewhat similar to the one posted with the 1.4 preview pdf, but not using the (I _think_) commercial foundation modules, but rather open source ones. #!/usr/bin/perl; ################################################################################### # Simple Perl->LSL XML-RPC Client # Version 1.0 # By Alondria LeFay # Syntax: slsend -c<channel> [-s<string>] [-i<integer>] # Options: # -c <channel> - (required) RemoteData Channel # -s <string> - (optional) String to send # -i <integer> - (optional) Integer to send # Example: slsend -c 7dab695e-78ab-7477-22a5-f7a7b1b359e4 -s "Send a string" -i 23123 ###################################################################################
# Uses the XML-RPC Perl Module from http://search.cpan.org/~rjray/RPC-XML-0.53/ # and the standard package Getopt::Std. use RPC::XML::Client; use Getopt::Std;
################################################################################### # SLSend($channel, $integer, $string) # Sends a XML packet to $channel containing $string and $integer ###################################################################################
sub SLSend($$$) { my $client = new RPC::XML::Client 'http://xmlrpc.colo.lindenlab.com/cgi-bin/xmlrpc.cgi'; my $req = RPC::XML::request->new("llRemoteData",({Channel => $_[0], IntValue => $_[1], StringValue => $_[2], SenderID => Foobar, MessageID => '32058262-3493-2ce7-1f07-0757f2ac16c1'})); my $res = $client->send_request($req); return $res->value; }
my %options; getopt('cis', \%options);
if (!$options{c}) { print "Syntax: slsend -c<channel> [-s<string>] [-i<integer>]\n"; exit; }
my $returned_data = SLSend($options{c}, $options{i}, $options{s}); foreach $i (sort keys %$returned_data) { printf "$i is $$returned_data{$i} \n"; }
|
Carnildo Greenacre
Flight Engineer
Join date: 15 Nov 2003
Posts: 1,044
|
07-06-2004 23:54
My Perl implementation, still a work in progress. Note that the ExpectXMLHashFromString function hasn't been tested yet. use warnings; use RPC::XML; use RPC::XML::Client;
$chan = 'aad755b9-7495-8a26-2353-6931114b8cd5';
# XML-RPC library sub XMLRPC_Init { $client = RPC::XML::Client->new('http://xmlrpc.secondlife.com/cgi-bin/xmlrpc.cgi'); }
# Send a string, return the "integer" part of the return sub ExpectXMLIntFromString { my $stringval = shift; my $raw_request = RPC::XML::request->new('llRemoteData', RPC::XML::struct->new(Channel => $chan, IntValue => 0, StringValue => $stringval)); my $response = $client->send_request($raw_request);
if($response->is_fault()) { print "Fault: ", $response->code, " ", $response->string, "\n"; return undef; } else { print "Data: ", $$response{IntValue}->value, "\n"; return $$response{IntValue}->value; } }
# Send a string, return the "string" part of the return sub ExpectXMLStringFromString { my $stringval = shift; my $raw_request = RPC::XML::request->new('llRemoteData', RPC::XML::struct->new(Channel => $chan, IntValue => 0, StringValue => $stringval)); my $response = $client->send_request($raw_request);
if($response->is_fault()) { print "Fault: ", $response->code, " ", $response->string, "\n"; return undef; } else { print "Data: ", $$response{StringValue}->value, "\n"; return $$response{StringValue}->value; } }
# Send a string, return a hash containing the "int" and "string" parts sub ExpectXMLHashFromString { my $stringval = shift; my $raw_request = RPC::XML::request->new('llRemoteData', RPC::XML::struct->new(Channel => $chan, IntValue => 0, StringValue => $stringval)); my $response = $client->send_request($raw_request);
if($response->is_fault()) { print "Fault: ", $response->code, " ", $response->string, "\n"; return undef; } else { print "Data: ", $$response{StringValue}->value, "\n"; return {StringValue => $$response{StringValue}->value, IntValue => $$response{IntValue}->value}; } }
# Example usage &XMLRPC_Init(); $sim_name = &ExpectXMLStringFromString("sim_name");
_____________________
perl -le '$_ = 1; (1 x $_) !~ /^(11+)\1+$/ && print while $_++;'
|
Hiro Yamamoto
Registered User
Join date: 1 May 2003
Posts: 44
|
python example
07-07-2004 12:18
#!/usr/bin/python
import xmlrpclib
def main(): rpcserver = xmlrpclib.ServerProxy('http://xmlrpc.secondlife.com/cgi-bin/xmlrpc.cgi') params = { 'Channel' : 'a7732aef-5fb1-316b-ab7d-a022e7f23fc2' , 'IntValue' : 42 , 'StringValue' : 'The Answer' } result = rpcserver.llRemoteData(params) print result
main()
note: i'm not sure if the misformed xml response thingiee has been fixed, if not you will need to install the sgmlop parser for python
|
Apotheus Silverman
I write code.
Join date: 17 Nov 2003
Posts: 416
|
07-08-2004 06:13
My basic C#.NET implementation without error checking or other goodies can be found in this thread.
|
Cienna Rand
Inside Joke
Join date: 20 Sep 2003
Posts: 489
|
Cocoa/WebKit
07-08-2004 07:06
Here is my Cocoa/WebKit implementation of a simple debug client. I wrote this during the 1.4 preview, and have not updated it since then so until I get un-lazy it will need the URL updated to the correct, live URL. Included is the entire XCode project set, built and run on Panther, I'm not sure about other versions. .sit.zip
_____________________
You can't spell have traffic without FIC. Primcrafters (Mocha 180,90) : Fine eyewear for all avatars SLOPCO (Barcola 180, 180) : Second Life Oil & Petroleum Company Landmarker : Social landmarking software Conversation : Coming soon!
|
Driftwood Nomad
Registered User
Join date: 10 May 2003
Posts: 451
|
08-12-2004 21:40
Any PHP examples? And are there any XML-RPC tutorials out there that explain setting up the server, creating a scripted XML-RPC object, and having them communicate? 
|
Radium Lumin
Pixel's Mom
Join date: 22 Jul 2003
Posts: 23
|
Part 1: Python Code for XML-RPC Server
08-14-2004 19:10
Hi, all! I'm posting some Python code for setting up an off-world XML-RPC server to feed data to an in-world client object. This particular example sends the 'uptime' status of my Linux server via XML-RPC, and the client displays that status. However, this example code is quite flexible, and can be used to feed any other data into SL. Part 1 (this) is some 'library' code used by the server app, which makes setting up the XML-RPC connection a snap. Part 2 is the actual server app. Part 3 will be the in-world client LSL code. # # SLComm -- Python to Second Life XML-RPC Communications. # by Radium Lumin # You are free to use this anyway you like. #
import xmlrpclib
class SLCommError(Exception): pass
class SLComm(object):
def __init__(self, channel): self._server = None try: self._server = \ xmlrpclib.ServerProxy("http://xmlrpc.secondlife.com/cgi-bin/xmlrpc.cgi") except xmlrpclib.Fault, what: print "XML-RPC data error (%s)." % what.faultString raise SLCommError except xmlrpclib.ProtocolError, what: print "XML-RPC transport error (%s)." % what.errmsg raise SLCommError self._channel = channel
def call(self, stringParam="", intParam=0): try: rval = self._server.llRemoteData({"Channel" : self._channel, \ "IntValue" : intParam, \ "StringValue" : stringParam}); except xmlrpclib.Fault, what: print "XML-RPC data error (%s)." % what.faultString raise SLCommError except xmlrpclib.ProtocolError, what: print "XML-RPC transport error (%s)." % what.errmsg raise SLCommError
_____________________
The Mad Toymaker
|
Radium Lumin
Pixel's Mom
Join date: 22 Jul 2003
Posts: 23
|
Part 2: Python Code for XML-RPC Server
08-14-2004 19:13
Here's the server app. #! /usr/bin/env python
# # Radium Server Status # XML-RPC feed server # by Radium Lumin # You can use this any way you like. #
import sys import time import commands import slcomm
def usage(): print "" print "Usage: serverstatus <channel>" print "Where <channel> is the SL XML-RPC channel to talk to." print ""
def getServerStatus(): """ Return a two-line summary of the system's OS name and release, and the system's uptime. """ return "\n".join([commands.getoutput("uname -r -o"), commands.getoutput("uptime")])
def wrap(text, width): """ A word-wrap function that preserves existing line breaks and most spaces in the text. Expects that existing line breaks are posix newlines (\n). """ return reduce(lambda line, word, width=width: '%s%s%s' % (line, ' \n'[(len(line[line.rfind('\n')+1:]) + len(word.split('\n',1)[0] ) >= width)], word), text.split(' ') )
def main(argv=None): if argv is None: argv = sys.argv[1:]
# We must specify the in-world object channel on the command line. if len(argv) != 1: usage() raise SystemExit # Establish a link to the SL XML-RPC server, and through it to # the channel our in-world client is listening on. link = slcomm.SLComm(argv[0])
while True: # Get the server status text. status = getServerStatus() # Wrap it nicely. status = wrap(status, 40).replace("\n", "\r\n") try: # Call the in-bound SL XML-RPC function, sending it the status # string. results = link.call(status) except slcomm.SLCommError: pass
# Wait 30 seconds for the next status update. time.sleep(30.0)
if __name__ == "__main__": sys.exit(main())
_____________________
The Mad Toymaker
|
Radium Lumin
Pixel's Mom
Join date: 22 Jul 2003
Posts: 23
|
Part 3: Python Code for XML-RPC Server
08-14-2004 19:20
And here's the in-world LSL code that displays the in-coming data. As you can see, it's a pretty simple data displayer via llSetText. You can use this method to display many different kinds of (short) data strings. // Radium Server Status // by Radium Lumin
key dataChannel = NULL_KEY;
default { state_entry() { // You wanna change this next line. :-) llSetText("Radium Server Status", <1.0, 0.0, 0.0>, 1.0); llTargetOmega(<0,0,1>, 2, 2); llOpenRemoteDataChannel(); }
touch_start(integer num) { // I need to get the data channel, 'cause my Linux server // app needs it in order to talk to this script. llWhisper(0, "Listening on data channel: " + (string)dataChannel); } remote_data(integer type, key channel, key msg_id, string sender, integer ival, string sval) { if (type == REMOTE_DATA_CHANNEL) { dataChannel = channel; // I need to get the data channel, 'cause my Linux server // app needs it in order to talk to this script. llWhisper(0, "Listening on data channel: " + (string)dataChannel); } else if (type == REMOTE_DATA_REQUEST) { // You wanna change this next line. :-) llSetText("Radium Server Status\n" + sval, <1.0, 0.0, 0.0>, 1.0); llRemoteDataReply(channel, msg_id, "Thank You", 0); } } }
_____________________
The Mad Toymaker
|
Huns Valen
Don't PM me here.
Join date: 3 May 2003
Posts: 2,749
|
08-17-2004 03:18
bumping thread for great justice
|
Champie Jack
Registered User
Join date: 6 Dec 2003
Posts: 1,156
|
10-22-2004 20:45
bump.
There was a PHP implementation that I was using before I cancelled my account (now reactivated with empty inventory, doh!). I could repost it, but I didn't write it. So, if you are the author, I think a repost would be appreciated.
Great threads like this deserve a bump.
Champie
|
Samhain Broom
Registered User
Join date: 1 Aug 2004
Posts: 298
|
Sorry if this sounds like a stupid question...
10-25-2004 12:17
What does it mean when you (in this most recent reply from Champie) say:
Bump
(what do you mean by that?)
_____________________
rm -rf /bin/ladden #beware of geeks bearing grifts
|
Champie Jack
Registered User
Join date: 6 Dec 2003
Posts: 1,156
|
10-25-2004 13:24
when you reply to a thread, the thread gets moved to the top of the list (1st page top). at first I just wanted to "bump" it to the top because ther was another thread where somebody asked about XML-RPC Implementations. So, rather than reply with a link, I just bumped the thread so that the author of the other thread would see it next time he logged in. Then I decided that I actually wanted to write a reply.  Champie
|
Samhain Broom
Registered User
Join date: 1 Aug 2004
Posts: 298
|
10-26-2004 12:56
Ah, thanks, I really do not spend much time in forums, except this one. Now I know! 
_____________________
rm -rf /bin/ladden #beware of geeks bearing grifts
|
Dan Medici
Registered User
Join date: 25 Jan 2004
Posts: 132
|
10-31-2004 21:58
Does anyone here have an example of a C++ implementation?
|