12-29-2006 18:58
The following is an example of how to use PHP to sent integer string pairs to and in-world object and then receive and display the integer string pair response. There isn't much more here that you can't find in various spots on LSLWiki, but I thought it would be useful to pull it all together in one place. Also, if you don't immediately want to implement the server side of this project you can use the generic XMLRPC Call Generator form on my website at www.secondlifehowto.com.

Here's what you do:
1. Create an object and add the following script to it:
CODE

// XML-RPC example

key gChannel; // my llRemoteData channel

DEBUG(list out)
{ // output debug info
llSay(0, llList2CSV(out));
}

default
{ // initialize XML-RPC
state_entry()
{
llOpenRemoteDataChannel(); // create an XML-RPC channel
// this will raise remote_data event REMOTE_DATA_CHANNEL when created
}

remote_data(integer type, key channel, key message_id, string sender, integer ival, string sval)
{
if (type == REMOTE_DATA_CHANNEL)
{ // channel created
DEBUG(["Channel opened", "REMOTE_DATA_CHANNEL", channel, message_id, sender, ival, sval]);
gChannel = channel;
llSay(0, "Ready to receive requests on channel \"" + (string)channel +"\"");
state go; // start handling requests
} else DEBUG(["Unexpected event type", type, channel, message_id, sender, ival, sval]);
}
}

state go
{ // handle requests
remote_data(integer type, key channel, key message_id, string sender, integer ival, string sval)
{
if (type == REMOTE_DATA_REQUEST)
{ // handle requests sent to us

DEBUG(["Request received", "REMOTE_DATA_REQUEST", channel, message_id, sender, ival, sval]);

// Set the default reply to the received data
string stringPortionOfReply = "Default Reply";
integer intPortionOfReply = 0;

if(sval == "Hello")
{
stringPortionOfReply = "Hi";
}

if(ival == 1234)
{
intPortionOfReply = 5678;
}

llRemoteDataReply(channel, message_id, stringPortionOfReply, intPortionOfReply);

} else DEBUG(["Unexpected event type:", type, channel, message_id, sender, ival, sval]);
}

state_exit()
{
llCloseRemoteDataChannel(gChannel); // clean up when you no longer want to handle requests
}
}


2. Add the following file to the server and save it as XMLRPCCallGenerator.html. This file is a simple form that allows you to fill in the channel you'll be communicating on and the string and integer values of your message. When you click submit it calls responsedisplay.php to do the real work.
CODE

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>
<head>
<title>XMLRPC Call Generator</title>
</head>

<body>

<form method="post" action="responsedisplay.php">
<P>
Key:
<input type="text" name="channel" size="38" maxlength="255" value="0d2bc7c3-9a2e-9aee-65b4-6c731c7f7a39">
</P>
<P>
String Message:
<input type="text" name="stringMessage" size="40" maxlength="255" value="Hello">
</P>
<P>
Int Message:
<input type="text" name="intMessage" size="40" maxlength="10" value="1234" />
</P>
<P>
<input type="submit" value="Submit">
</P>
</form>

</body>
</html>


3. Add the following to a file and save it on your server under the name responsedisplay.php. This extracts the values posted to it from the form XMLRPCCallGenerator.html, sends the values as a message to the in world object specified by the channel used, and print out the response from the object on the screen.

CODE

<html>
<head>

<title>Response Received</title>

</head>
<body>

<?php
function postToHost($host, $path, $data_to_send) {
$fp = fsockopen($host, 80);
fputs($fp, "POST $path HTTP/1.1\r\n");
fputs($fp, "Host: $host\r\n");
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-length: ". strlen($data_to_send) ."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $data_to_send);
while(!feof($fp)) {
$res .= fgets($fp, 128);
}
fclose($fp);
return substr($res, strpos($res, "\r\n\r\n"));;
}

function parseResponse($response) {
$result = array();
if (preg_match_all('#<name>(.+)</name><value><(string|int)>(.*)</\2></value>#U', $response, $regs, PREG_SET_ORDER)) {
foreach($regs as $key=>$val) {
$result[$val[1]] = $val[3];
}
}
return $result;
}

function sendRequest($channel, $intValue, $stringValue) {
$channel = htmlspecialchars($channel);
$int = (int)$intValue;
$string = htmlspecialchars($stringValue);

$data = '<?xml version="1.0"?>';
$data .= '<methodCall>';
$data .= '<methodName>llRemoteData</methodName>';
$data .= '<params><param><value><struct>';
$data .= '<member><name>Channel</name><value><string>'.$channel.'</string></value></member>';
$data .= '<member><name>IntValue</name><value><int>'.$int.'</int></value></member>';
$data .= '<member><name>StringValue</name><value><string>'.$string.'</string></value></member>';
$data .= '</struct></value></param></params></methodCall>';

return parseResponse(postToHost("xmlrpc.secondlife.com","/cgi-bin/xmlrpc.cgi", $data));
}


$channel = $_POST["channel"];
$stringMessage = $_POST["stringMessage"];
$intMessage = $_POST["intMessage"];
$responseReceived = sendRequest($channel,$intMessage,$stringMessage);

?>
You sent to Second Life the following int,string:
<P>
<?php echo $intMessage; ?>,<?php echo $stringMessage; ?>
</P>
<P>
The object you talked to replied with the following int,string:
<P>
<?php echo $responseReceived["IntValue"]; ?>,
<?php echo $responseReceived["StringValue"]; ?>
</P>

</body>
</html>