Um was soll es in diesem TechTalk #4 gehen? Wolltet ihr nicht auch schon immer jemanden einmal das Licht auf Kommando ausknipsen können? Wie von Zauberhand? Genau darum geht es in diesem Tutorial. Auf meiner Homebase-Werkstatt unter Adder (73,189,57) steht meine Experimentalkuppel. Oben auf dem Dach ist ein Partikeleffekt in einer Glauskugel. Genau, mit diesen folgenden beiden Links könnt ihr jetzt und hier durch die folgenden beiden Links das Partikelsystem an bzw. ausknipsen (SURL: http://slurl.com/secondlife/Adder/75/208/55) !!!!!
Probiert es einfach aus:
Aus
An
Die Technik ist “quite simple!”. Das Zauberwort heisst XML-RPCs! Also los geht’s.
SL-XML-RPC-Server-Endpunkt bei Lindenlabs
Das Prim mit den Partikeln stellt den SL-seitigen XML-RPC-Server dar. Der PHP-Client ruft die XML-RPC-Methode llRemoteData der Linden-Labs-Server auf. Der XML-RPC-Methodenaufruf sieht wie folgt aus:
Die XML-RPC-Methode ist über das CGI unter http://xmlrpc.secondlife.com/cgi-bin/xmlrpc.cgi erreichbar
<methodCall> <methodName>llRemoteData</methodName> <params> <param> <value> <struct> <member> <name>Channel</name> <value> <string> 535d455b-a722-29fd-c0c9-6e5a9aa875de </string> </value> </member> <member> <name>IntValue</name> <value><int>0</int></value> </member> <member> <name>StringValue</name> <value><string>test</string></value> </member> </struct> </value> </param> </params> </methodCall>
Sehr wichtig ist hierbei die UUID des Channels, unter dem euer XML-RPC-Server erreichbar ist. Die UUID wird vom aufrufenden XML-RPC-PHP-Client benötigt, um dem richtigen Channel in Second Life® eine Nachricht zu übermitteln. Dieser Channel wird von dem SL-XML-RPC-Server erzeugt, welcher in LSL implementiert ist. Die UUID ist nicht zu verwechseln mit der UUID des Prims, der den XML-RPC-Channel implementiert.
SL-XML-RPC-Server
Installation eines serverseitgen XML-RPC Endpunktes in Second Life®
state_entry() { llOpenRemoteDataChannel(); }
Der Aufruf dieser Funktion bewirkt, das die Callback-Funktion remote_data(integer type, key channel, key message_id, string sender, integer ival, string sval) aufgerufen wird:
Die Callback-Methode, wird aufgerufen, sobald der XML-RPC-Channel installiert wurde durch den Aufruf llRemoteDataChannel
remote_data(integer type, key channel, key message_id, string sender, integer ival, string sval) { if(type == REMOTE_DATA_CHANNEL) { gChannel = channel; llSay(0, "Ready to receive requests on channel" + (string)channel); state go; } }
Ganz entscheident ist hier die UUID des Channels, welche in der globalen Variable gChannel gespeichert wird. Diese UUID wird benötigt, um im PHP-Client den korrekten XML-RPC-Call aufzubauen. Hier nochmal das Fragment des XML-RPC-Requests, welcher später vom PHP-XML-RPC-Client benötigt wird:
Die Channel-Variable des XML-RPC-Requests, welcher der PHP-Client erzeugt, nutzt die UUID, welche im SL-XML-RPC-Server erzeugt wurde (LSL-Variable gChannel bzw. channel)
<member> <name>Channel</name> <value> <string> 535d455b-a722-29fd-c0c9-6e5a9aa875de </string> </value> </member>
Der Rest ist eigentlich ganz simpel.
Der XML-RPC-Response wird durch den Aufruf llRemoteDataReply() aufgebaut
state go { remote_data(integer type, key channel, key message_id, string sender, integer ival, string sval) { if(type == REMOTE_DATA_REQUEST) { if(sval=="on") { llRemoteDataReply(channel, message_id, "switching on", 1); llSay(0,"XML-RPC: on"); wolke_an(); } else if (sval=="off") { llRemoteDataReply(channel, message_id, "switching off", 1); llSay(0,"XML-RPC: off"); wolke_aus(); } else { llRemoteDataReply(channel, message_id, "failed", 0); } } }
Erhält man einen Aufruf mit der Message on oder off rufe ich hier entsprechend die Funktion wolke_an() bzw. wolke_aus() auf. Die Funktion wolke_an() erzeugt das Partikelsystem auf meiner Experimentalkuppel, wolke_aus() schaltet das Partikelsystem aus.
PHP-XML-RPC-Client
Der PHP-Client ist sehr simpel:
Hier ist der PHP-Client-Code zu sehen, welcher den XML-RPC-Request erzeugt, Der XML-RPC-Response wird durch den Aufruf llRemoteDataReply() im LSL-Server aufgebaut.
require('./wp-includes/class-IXR.php'); if(isset($_GET['switch'])) { $switch=$_GET['switch']; if($switch=='on') { $params = new RPCStruct(' 535d455b-a722-29fd-c0c9-6e5a9aa875de', 0, 'on'); } else if($switch=='off') { $params = new RPCStruct(' 535d455b-a722-29fd-c0c9-6e5a9aa875de', 0, 'off'); } $client = new IXR_Client( 'http://xmlrpc.secondlife.com/cgi-bin/xmlrpc.cgi'); $client->debug = false; $client->query('llRemoteData',$params); $r = $client->getResponse(); }
Um den XML-RPC-Request aus PHP heraus aufzubauen benutze ich die IXR Library von Simon Willson in der Version 1.7. Ein wenig knifflig war lediglich der Aufbau des XML-RPC-Requests wie von Linden Labs gefordert, nämlich ein XML-RPC-Struct. Dafür war es nötig eine kleine Wrapper-Klasse zu schreiben, welche dann von IXR entsprechend als XML-RPC-Struct umgewandelt wird:
Klassen-Wrapper, damit IXR ein XML-RPC-Struct aufbaut
class RPCStruct { var $Channel; var $IntValue; var $StringValue; function RPCStruct($channel, $intval, $strval) { $this->Channel = $channel; $this->IntValue = $intval; $this->StringValue = $strval; } }
Das war’s, zumindest ist das aus meiner Sicht die Essenz des Ganzen. Also, dann bis zum nächsten Mal.
by Patrick Wunderland
Download