Difference between revisions of "Category:LSL XML-RPC/ja"

From Second Life Wiki
Jump to navigation Jump to search
(Initial translation)
 
m
 
(One intermediate revision by one other user not shown)
Line 1: Line 1:
{{LSL Header/ja|ml=*}}{{LSLC/ja|}}{{LSLC/ja|Communications}}
{{Multi-lang}}
{{Wikipedia|1=XML-RPC|2=XML-RPC|lang=ja}} は外部システムへのプロシージャコール (機能呼び出し) 送信に使われるひとつの標準です。そこでは、外部システムが扱う {{Wikipedia|1=XML|2=XML|lang=ja}} データが HTTP でやり取りされます。
{{LSL Header/ja|ml=*}}
{{LSLC/ja|}}{{LSLC/ja|Communications}}
[https://ja.wikipedia.org/wiki/XML-RPC XML-RPC] は外部システムへのプロシージャコール (機能呼び出し) 送信に使われるひとつの標準です。そこでは、外部システムが扱う [https://ja.wikipedia.org/wiki/Extensible_Markup_Language XML] データが HTTP でやり取りされます。


LSL は XML-RPC 要求を受け取ると、それを指定のプリムへ渡します。プリムはコネクションを確立しないかもしれませんが、応答は可能であり、サーバとの双方向通信を維持します。これらの応答は ({{LSLG/ja|Email}} や {{LSLGC/ja|HTTP}} 要求に比べると) Second Life 外との大規模なデータのやりとりを可能にしてくれるようです。
LSL は XML-RPC 要求を受け取ると、それを指定のプリムへ渡します。プリムはコネクションを確立しないかもしれませんが、応答は可能であり、サーバとの双方向通信を維持します。これらの応答は ({{LSLG/ja|Email}} や {{LSLGC|HTTP/ja|HTTP通信}} 要求に比べると) Second Life 外との大規模なデータのやりとりを可能にしてくれるようです。  


=== 注意:{{Anchor|NOTE:}} ===
=== 注意: ===


XML-RPC 要求は、フロントエンド サーバが過負荷となるため、しばしばタイムアウトします。LL (Linden Lab) は定期的にサーバのハードウェアを更新し続けていますが、未だに信頼性には欠けます。(サーバが 1 つだけというボトルネックゆえに) XML-RPC の設計に拡張性が無く、そのサービスは "推奨されない" と LL の開発者は勧告してきました。彼らは HTTP ポーリング (訳注: 外部からの要求を待つのでなく、要求の有無を相手側へ一定時間おきに確認しにゆく手法。HTTP polling) を代替とするよう提案しています。XML-RPC 要求がタイムアウトした場合、そのスクリプトの remote_data イベントは発生するかもしれませんし、発生しないかもしれません。(後者の場合、スクリプトは無反応になります。)
{{KBcaution|width=100%|XML-RPC 要求は、フロントエンド サーバが過負荷となるため、しばしばタイムアウトします。LL (Linden Lab) は定期的にサーバのハードウェアを更新し続けていますが、未だに信頼性には欠けます。(サーバが 1 つだけというボトルネックゆえに) XML-RPC の設計に拡張性が無く、そのサービスは "推奨されない" と LL の開発者は勧告してきました。彼らは [[HTTP_Polling/ja|HTTP ポーリング]] を代替とするよう提案しています。XML-RPC 要求がタイムアウトした場合、そのスクリプトの remote_data イベントは発生するかもしれませんし、発生しないかもしれません。(後者の場合、スクリプトは無反応になります。) }}


=== 実装に関する重要な注意:{{Anchor|IMPORTANT IMPLEMENTATION NOTE:}} ===
=== 実装に関する重要な注意: ===


現在の XML-RPC の実装では、フロントエンド サーバ (xmlrpc.secondlife.com) で同時にキューに入ることができる要求はただ 1 個だけです。同じデータ チャネルに新しい要求があった場合、それは既存のものを上書きします。これは XML-RPC 通信の設計にとって深刻な問題です。なぜなら XML-RPC 通信では in-world のオブジェクトが応答可能になる前に要求を受け取る可能性があるからです。加えて、{{LSLG/ja|llRemoteDataReply}} 関数の 3 秒間の遅延が問題をより深刻にします。
現在の XML-RPC の実装では、フロントエンド サーバ (xmlrpc.secondlife.com) で同時にキューに入ることができる要求はただ 1 個だけです。同じデータ チャネルに新しい要求があった場合、それは既存のものを上書きします。これは XML-RPC 通信の設計にとって深刻な問題です。なぜなら XML-RPC 通信では in-world のオブジェクトが応答可能になる前に要求を受け取る可能性があるからです。加えて、{{LSLG/ja|llRemoteDataReply}} 関数の 3 秒間の遅延が問題をより深刻にします。


分かっている問題は以下のとおりです: XML-RPC を介して in-world のオブジェクト (何らかの処理を行なって llRemoteDataReply 関数で応答を返すスクリプトが入っている) に複数の要求を立て続けに送ると、先に送られた要求ほど ({{LSLG/ja|remote_data}} イベントを発生させなければならないのに) フロントエンド サーバで取りこぼされる可能性があります。その結果、先の要求に対して、後の要求に関する応答を返してしまいます。本来ならば先の要求に関して、外部アプリケーションに対しタイムアウトが返るところです。
分かっている問題は以下のとおりです: XML-RPC を介して in-world のオブジェクト (何らかの処理を行なって {{LSLG/ja|llRemoteDataReply}} 関数で応答を返すスクリプトが入っている) に複数の要求を立て続けに送ると、先に送られた要求ほど ([[Remote_data/ja|remote_data]] イベントを発生させなければならないのに) フロントエンド サーバで取りこぼされる可能性があります。その結果、先の要求に対して、後の要求に関する応答を返してしまいます。本来ならば先の要求に関して、外部アプリケーションに対しタイムアウトが返るところです。


結局のところ、XML-RPC を使って何らかの重要な処理を行なおうとするならば、各 RPC チャネルに対する全ての要求に連番をつけて管理するよう、外部のクライアント アプリケーションを設計しなければならないでしょう。すなわちこれは、次の要求を送る前に、前の要求に関する応答が帰ってくるのを待たなけれならない事を意味します。応答の受け取りを気にしないで済むならば、これは問題ではありません。なぜならキューの問題がどうであろうと、全ての要求はスクリプトへ渡されたように見えるからです。
結局のところ、XML-RPC を使って何らかの重要な処理を行なおうとするならば、各 RPC チャネルに対する全ての要求に連番をつけて管理するよう、外部のクライアント アプリケーションを設計しなければならないでしょう。すなわちこれは、次の要求を送る前に、前の要求に関する応答が帰ってくるのを待たなけれならない事を意味します。応答の受け取りを気にしないで済むならば、これは問題ではありません。なぜならキューの問題がどうであろうと、全ての要求はスクリプトへ渡されたように見えるからです。


なお llRemoteDataReply 関数の 3 秒間の遅延から逃れる方法はありません。例えば multiple-slave-comm-script といった手法 (訳注: {{LSLG/ja|llMessageLinked}} 関数を使い複数のスクリプトに並行処理をさせる手法のことか) は使えません。XML-RPC チャネルはスクリプト固有のものであり、オブジェクト固有のものではないからです。
なお {{LSLG/ja|llRemoteDataReply}} 関数の 3 秒間の遅延から逃れる方法はありません。例えば multiple-slave-comm-script といった、 {{LSLG/ja|llMessageLinked}} 関数を使い複数のスクリプトに同じ発生源からの返答を並行で処理させる手法は使えません。XML-RPC チャネルはスクリプト固有のものであり、オブジェクト固有のものではないからです。


これ以上の情報については公式フォーラムの[http://forums.secondlife.com/showthread.php?t=158437 このスレッド]と[http://forums.secondlife.com/showthread.php?p=1379244 このスレッド]を参照してください。
これ以上の情報については公式フォーラムの[http://forums.secondlife.com/showthread.php?t=158437 このスレッド]と[http://forums.secondlife.com/showthread.php?p=1379244 このスレッド]を参照してください。  


== 参考資料{{Anchor|Other Resources}} ==
==参考資料==
* [http://www.xmlrpc.com/ XMLRPC.com]
* [http://www.xmlrpc.com/ XMLRPC.com]
* [http://scripts.incutio.com/xmlrpc/ Incutio's XML-RPC PHP library]
* [http://scripts.incutio.com/xmlrpc/ Incutio's XML-RPC PHP library]
* [http://perisic.com/sl/ A simple form to launch an XMLRPC request into Second Life]
* [http://perisic.com/sl/ A simple form to launch an XMLRPC request into Second Life]


== 例{{Anchor|Examples}} ==
==例==


= php =
=php=


外部サーバとして XML-RPC を初期化するには、ある種の Web アプリケーションが必要です。
外部サーバとして XML-RPC を初期化するには、ある種の Web アプリケーションが必要です。 Web アプリケーションを作成する言語の一つが PHP です。 PHP を使い Web サーバから SL 内のスクリプトへ XML-RPC メッセージをどのように送信するかの例を以下に示します:
Web アプリケーションを作成する言語の一つが PHP です。
<source lang="php"><?php
PHP を使い Web サーバから SL 内のスクリプトへ XML-RPC メッセージをどのように送信するかの例を以下に示します:
<php><?php
echo '<pre>';
echo '<pre>';
$channel = ""; //Fill in the channel you are using (key)
$channel = ""; //Fill in the channel you are using (key)
Line 78: Line 78:
return $buf;  
return $buf;  
}  
}  
?></php>
?></source>


= perl =
=perl=


Second Life 内のオブジェクトにアクセスするための perl コード、及びそれに対応する LSL のコードは以下のとおりです。perl コードは RPC::XML モジュールを使います。この perl コードはコマンドラインで実行できます。それは RPC 関連の perl オブジェクトを作成し、グリッド内に rez された SL オブジェクトへメッセージを送信します。perl コードに、SL オブジェクトの UUID を与えなければならない点に注意してください。
Second Life 内のオブジェクトにアクセスするための perl コード、及びそれに対応する LSL のコードは以下のとおりです。perl コードは RPC::XML モジュールを使います。この perl コードはコマンドラインで実行できます。それは RPC 関連の perl オブジェクトを作成し、グリッド内に rez された SL オブジェクトへメッセージを送信します。perl コードに、SL オブジェクトの UUID を与えなければならない点に注意してください。


この perl コードは "Message to pass" という文字列と "2007" という数字を含んだメッセージを送信します。LSL コードは "I got it" という文字列と "2008" という数字を応答として返します。
この perl コードは "Message to pass" という文字列と "2007" という数字を含んだメッセージを送信します。LSL コードは "I got it" という文字列と "2008" という数字を応答として返します。  


<perl>#!/usr/bin/perl
<source lang="perl">#!/usr/bin/perl
#  
#  


Line 135: Line 135:
       print "$lupe: $val\n";
       print "$lupe: $val\n";
     }
     }
}</perl>
}</source>




= Java =
=Java=


この Java コードは the org.apache.xmlrpc ライブラリを使っています。これに関する jar フィルは http://www.perisic.com/xmlrpc/cis69mc.jar にあります。(これを使って以下のコードはテストされました。) 必要ならば Java と XMLRPC に関する簡単なイントロダクションを http://perisic.com/xmlrpc で参照してください。
この Java コードは the org.apache.xmlrpc ライブラリを使っています。これに関する jar ファイルは http://www.perisic.com/xmlrpc/cis69mc.jar にあります。(これを使って以下のコードはテストされました。) 必要ならば Java と XMLRPC に関する簡単なイントロダクションを http://perisic.com/xmlrpc で参照してください。
* SLClient.java という名前のファイルにあるコードを保存し、上記の URL から cis69mc.jar という jar ファイルをダウンロードしてください。
* SLClient.java という名前のファイルにあるコードを保存し、上記の URL から cis69mc.jar という jar ファイルをダウンロードしてください。
* '<add channel id here!!!>' とある場所にチャネル ID を追加してください。結果的にその行は <code>theData.put("Channel", "24a2c834-c984-9209-78df-20608d4c8ade");</code> といった具合になります。
* '<add channel id here!!!>' とある場所にチャネル ID を追加してください。結果的にその行は theData.put("Channel", "24a2c834-c984-9209-78df-20608d4c8ade"); といった具合になります。
* 次のコマンドでコードをコンパイルします: javac -classpath "cis69mc.jar;." SLClient.jar (未チェックあるいは安全でない操作という警告が出るかもしれませんが無視してください。)
* 次のコマンドでコードをコンパイルします: javac -classpath "cis69mc.jar;." SLClient.jar (未チェックあるいは安全でない操作という警告が出るかもしれませんが無視してください。)
* 次のコマンドでコードを実行してください: java -classpath "cis69mc.jar;." SLClient
* 次のコマンドでコードを実行してください: java -classpath "cis69mc.jar;." SLClient


<java>import java.util.*;
<source lang="java">import java.util.*;
import org.apache.xmlrpc.*;
import org.apache.xmlrpc.*;


Line 167: Line 167:
   }
   }
   }
   }
}</java>
}</source>


= Visual Basic 6 =
=Visual Basic 6=


この Visual Basic 6 コードは Microsoft WinSock 6.0 コントロールを使います。プロジェクトを新規作成し、フォームに Winsock コントロールを配置してください。
この Visual Basic 6 コードは Microsoft WinSock 6.0 コントロールを使います。プロジェクトを新規作成し、フォームに Winsock コントロールを配置してください。


<vb>
<source lang="vb">
Dim Channel As String
Dim Channel As String
Dim IntValue As Integer
Dim IntValue As Integer
Line 210: Line 210:
     Winsock1.SendData str
     Winsock1.SendData str
End Sub
End Sub
</vb>
</source>


= Command line curl =
=Command line curl=
コマンドラインで XML-RPC をデバッグしたいならば、"curl" が使えます。rpc.xml という名前のファイルに以下の内容を保存してください。その際、UUID をスクリプトのチャネル ID に置き換えてください:


コマンドラインで XML-RPC をデバッグしたいならば、"curl" が使えます。<code>rpc.xml</code> という名前のファイルに以下の内容を保存してください。その際、UUID をスクリプトのチャネル ID に置き換えてください:
<source lang="xml">
 
<xml>
<?xml version="1.0"?>
<?xml version="1.0"?>
<methodCall>
<methodCall>
Line 241: Line 240:
     </params>
     </params>
</methodCall>
</methodCall>
</xml>
</source>


その上で、curl を以下のように実行し、XMLRPC サーバに POST します。
その上で、curl を以下のように実行し、XMLRPC サーバに POST します。


<code>
<source lang="bash">
curl --verbose --data "@rpc.xml" http://xmlrpc.secondlife.com/cgi-bin/xmlrpc.cgi
curl --verbose --data "@rpc.xml" http://xmlrpc.secondlife.com/cgi-bin/xmlrpc.cgi
</code>
</source>


= LSL Server Code =
=LSL Server Code=


(上記の例に) 対応する LSL コードは以下の通りです。(オブジェクト内のスクリプトにコピー&amp;ペーストし、保存し、rez してください。チャネル ID およびその他の情報がメッセージとして表示されます。) :
(上記の例に) 対応する LSL コードは以下の通りです。(オブジェクト内のスクリプトにコピー&ペーストし、保存し、rez してください。チャネル ID およびその他の情報がメッセージとして表示されます。) :  


<lsl>key remoteChannel;
<source lang="lsl2">key remoteChannel;
init() {
init() {
     llOpenRemoteDataChannel(); // create an XML-RPC channel
     llOpenRemoteDataChannel(); // create an XML-RPC channel
Line 312: Line 311:
         }
         }
     }
     }
}</lsl>
}</source>

Latest revision as of 04:37, 18 December 2015

XML-RPC は外部システムへのプロシージャコール (機能呼び出し) 送信に使われるひとつの標準です。そこでは、外部システムが扱う XML データが HTTP でやり取りされます。

LSL は XML-RPC 要求を受け取ると、それを指定のプリムへ渡します。プリムはコネクションを確立しないかもしれませんが、応答は可能であり、サーバとの双方向通信を維持します。これらの応答は (EmailHTTP通信 要求に比べると) Second Life 外との大規模なデータのやりとりを可能にしてくれるようです。

注意:

KBcaution.png 重要 XML-RPC 要求は、フロントエンド サーバが過負荷となるため、しばしばタイムアウトします。LL (Linden Lab) は定期的にサーバのハードウェアを更新し続けていますが、未だに信頼性には欠けます。(サーバが 1 つだけというボトルネックゆえに) XML-RPC の設計に拡張性が無く、そのサービスは "推奨されない" と LL の開発者は勧告してきました。彼らは HTTP ポーリング を代替とするよう提案しています。XML-RPC 要求がタイムアウトした場合、そのスクリプトの remote_data イベントは発生するかもしれませんし、発生しないかもしれません。(後者の場合、スクリプトは無反応になります。)

実装に関する重要な注意:

現在の XML-RPC の実装では、フロントエンド サーバ (xmlrpc.secondlife.com) で同時にキューに入ることができる要求はただ 1 個だけです。同じデータ チャネルに新しい要求があった場合、それは既存のものを上書きします。これは XML-RPC 通信の設計にとって深刻な問題です。なぜなら XML-RPC 通信では in-world のオブジェクトが応答可能になる前に要求を受け取る可能性があるからです。加えて、llRemoteDataReply 関数の 3 秒間の遅延が問題をより深刻にします。

分かっている問題は以下のとおりです: XML-RPC を介して in-world のオブジェクト (何らかの処理を行なって llRemoteDataReply 関数で応答を返すスクリプトが入っている) に複数の要求を立て続けに送ると、先に送られた要求ほど (remote_data イベントを発生させなければならないのに) フロントエンド サーバで取りこぼされる可能性があります。その結果、先の要求に対して、後の要求に関する応答を返してしまいます。本来ならば先の要求に関して、外部アプリケーションに対しタイムアウトが返るところです。

結局のところ、XML-RPC を使って何らかの重要な処理を行なおうとするならば、各 RPC チャネルに対する全ての要求に連番をつけて管理するよう、外部のクライアント アプリケーションを設計しなければならないでしょう。すなわちこれは、次の要求を送る前に、前の要求に関する応答が帰ってくるのを待たなけれならない事を意味します。応答の受け取りを気にしないで済むならば、これは問題ではありません。なぜならキューの問題がどうであろうと、全ての要求はスクリプトへ渡されたように見えるからです。

なお llRemoteDataReply 関数の 3 秒間の遅延から逃れる方法はありません。例えば multiple-slave-comm-script といった、 llMessageLinked 関数を使い複数のスクリプトに同じ発生源からの返答を並行で処理させる手法は使えません。XML-RPC チャネルはスクリプト固有のものであり、オブジェクト固有のものではないからです。

これ以上の情報については公式フォーラムのこのスレッドこのスレッドを参照してください。

参考資料

php

外部サーバとして XML-RPC を初期化するには、ある種の Web アプリケーションが必要です。 Web アプリケーションを作成する言語の一つが PHP です。 PHP を使い Web サーバから SL 内のスクリプトへ XML-RPC メッセージをどのように送信するかの例を以下に示します:

<?php
	echo '<pre>';
	$channel = ""; //Fill in the channel you are using (key)
	$intvalue = ""; //Fill in the intvalue you are using (integer)
	$strvalue = ""; //Fill in the strvalue you are using (string)
	$xmldata = "<?xml version=\"1.0\"?><methodCall><methodName>llRemoteData</methodName>
<params><param><value><struct>
<member><name>Channel</name><value><string>".$channel."</string></value></member>
<member><name>IntValue</name><value><int>".$intvalue."</int></value></member>
<member><name>StringValue</name><value><string>".$strvalue."</string></value></member>
</struct></value></param></params></methodCall>";
	echo sendToHost("xmlrpc.secondlife.com", "POST", "/cgi-bin/xmlrpc.cgi", $xmldata);
	echo '</pre>';
	
	function sendToHost($host,$method,$path,$data,$useragent=0)
	{ 
		$buf="";
		// Supply a default method of GET if the one passed was empty 
		if (empty($method)) 
			$method = 'GET'; 
		$method = strtoupper($method); 
	
		$fp = fsockopen($host, 80, $errno, $errstr, 30);
	
		if( !$fp )
		{
			$buf = "$errstr ($errno)<br />\n";
		}else
		{
			if ($method == 'GET') 
			$path .= '?' . $data; 
			fputs($fp, "$method $path HTTP/1.1\r\n"); 
			fputs($fp, "Host: $host\r\n"); 
			fputs($fp, "Content-type: text/xml\r\n"); 
			fputs($fp, "Content-length: " . strlen($data) . "\r\n"); 
			if ($useragent) 
				fputs($fp, "User-Agent: MSIE\r\n"); 
			fputs($fp, "Connection: close\r\n\r\n"); 
			if ($method == 'POST') 
				fputs($fp, $data); 
			while (!feof($fp)) 
				$buf .= fgets($fp,128); 
			fclose($fp); 
		}
		return $buf; 
	} 
?>

perl

Second Life 内のオブジェクトにアクセスするための perl コード、及びそれに対応する LSL のコードは以下のとおりです。perl コードは RPC::XML モジュールを使います。この perl コードはコマンドラインで実行できます。それは RPC 関連の perl オブジェクトを作成し、グリッド内に rez された SL オブジェクトへメッセージを送信します。perl コードに、SL オブジェクトの UUID を与えなければならない点に注意してください。

この perl コードは "Message to pass" という文字列と "2007" という数字を含んだメッセージを送信します。LSL コードは "I got it" という文字列と "2008" という数字を応答として返します。

#!/usr/bin/perl
# 

use RPC::XML;
use RPC::XML::Parser;
use RPC::XML::Client;

my $llURL = "http://xmlrpc.secondlife.com/cgi-bin/xmlrpc.cgi";
$P = RPC::XML::Parser->new();

my $cli = RPC::XML::Client->new($llURL);
my $req = RPC::XML::request->new(
        "llRemoteData",
        {'Channel' => RPC::XML::string->new("UUID for the open channel from the object GOES HERE!"),
        'IntValue' => RPC::XML::int->new(2007),
        'StringValue' => RPC::XML::string->new("message to pass")});

#  Print out the message to send
print "ref(req): ",ref($req),"\n";
$xml = $req->as_string();
print "Length: ",$req->length,"\n\n",$xml,"\n\n";

$res = $P->parse($xml);
print ref($res),"\n";
if (ref($res)) {
    %h = %{$res->args->[0]->value};
    foreach $lupe (keys %h) {
       print "$lupe: $h{$lupe}\n";
    }
}

#  Submit the request to send the information above.
my $resp = $cli->send_request($req);


#  Print out the response
print "\n\n\nResponse\n";
print "ref(resp): ",ref($resp),"\n";
$xml = $resp->as_string();
print "Length: ",$resp->length,"\n\n",$xml,"\n\n";

$res = $P->parse($xml);
print ref($res),"\n";
if (ref($res)) {
    %h = %{$res->value};
    foreach $lupe (keys %h) {
       $val =  $h{$lupe};
       print "$lupe: $val\n";
    }
}


Java

この Java コードは the org.apache.xmlrpc ライブラリを使っています。これに関する jar ファイルは http://www.perisic.com/xmlrpc/cis69mc.jar にあります。(これを使って以下のコードはテストされました。) 必要ならば Java と XMLRPC に関する簡単なイントロダクションを http://perisic.com/xmlrpc で参照してください。

  • SLClient.java という名前のファイルにあるコードを保存し、上記の URL から cis69mc.jar という jar ファイルをダウンロードしてください。
  • '<add channel id here!!!>' とある場所にチャネル ID を追加してください。結果的にその行は theData.put("Channel", "24a2c834-c984-9209-78df-20608d4c8ade"); といった具合になります。
  • 次のコマンドでコードをコンパイルします: javac -classpath "cis69mc.jar;." SLClient.jar (未チェックあるいは安全でない操作という警告が出るかもしれませんが無視してください。)
  • 次のコマンドでコードを実行してください: java -classpath "cis69mc.jar;." SLClient
import java.util.*;
import org.apache.xmlrpc.*;

public class SLClient {
 public static void main (String [] args) {
  try {
   Hashtable theData = new Hashtable(); 
   XmlRpcClient server = new XmlRpcClient("http://xmlrpc.secondlife.com/cgi-bin/xmlrpc.cgi"); //
   theData.put("Channel", "<add channel id here!!!>"); 
   theData.put("IntValue", 2483); 
   theData.put("StringValue", "The date is: "+ (new Date()).toString() ); 
   Vector params = new Vector(); 
   params.add(theData); 
   
   Object result = server.execute("llRemoteData", params ); 
  
  } catch (Exception exception) {
   System.err.println("SL_Client: " + exception);
   exception.printStackTrace(); 
   }
  }
}

Visual Basic 6

この Visual Basic 6 コードは Microsoft WinSock 6.0 コントロールを使います。プロジェクトを新規作成し、フォームに Winsock コントロールを配置してください。

Dim Channel As String
Dim IntValue As Integer
Dim StrValue As String
Dim XMLData As String

Private Sub Form_Load()
    Channel = "<add channel id here!!!>"
    IntValue = 2007
    StrValue = "This is a test string."
    XMLData = "<?xml version=""1.0""?><methodCall><methodName>llRemoteData</methodName><params><param><value><struct>"
    XMLData = XMLData & "<member><name>Channel</name><value><string>" & Channel & "</string></value></member>"
    XMLData = XMLData & "<member><name>IntValue</name><value><int>" & CStr(IntValue) & "</int></value></member>"
    XMLData = XMLData & "<member><name>StringValue</name><value><string>" & StrValue & "</string></value></member>"
    XMLData = XMLData & "</struct></value></param></params></methodCall>"

    Winsock1.Connect "xmlrpc.secondlife.com", 80
End Sub

Private Sub Winsock1_Connect()
    WinsockSend "POST /cgi-bin/xmlrpc.cgi HTTP/1.1" & vbCrLf
    WinsockSend "Host: xmlrpc.secondlife.com" & vbCrLf
    WinsockSend "Content-type: text/xml" & vbCrLf
    WinsockSend "Content-length: " & CStr(Len(XMLData)) & vbCrLf
    WinsockSend "Connection: close" & vbCrLf & vbCrLf
    WinsockSend XMLData & vbCrLf
End Sub

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
    Dim TempStr As String
    Winsock1.GetData TempStr
    MsgBox TempStr
End Sub

Sub WinsockSend(str As String)
    Winsock1.SendData str
End Sub

Command line curl

コマンドラインで XML-RPC をデバッグしたいならば、"curl" が使えます。rpc.xml という名前のファイルに以下の内容を保存してください。その際、UUID をスクリプトのチャネル ID に置き換えてください:

<?xml version="1.0"?>
<methodCall>
    <methodName>llRemoteData</methodName>
    <params>
        <param>
            <value>
                <struct>
                    <member>
                        <name>Channel</name>
                        <value><string>1ee246fc-e60d-2fd3-6242-f5fc5d19850f</string></value>
                    </member>
                    <member>
                        <name>IntValue</name>
                        <value><int>42</int></value>
                    </member>
                    <member>
                        <name>StringValue</name>
                        <value><string>Hello, world!</string></value>
                    </member>
                </struct>
            </value>
        </param>
    </params>
</methodCall>

その上で、curl を以下のように実行し、XMLRPC サーバに POST します。

curl --verbose --data "@rpc.xml" http://xmlrpc.secondlife.com/cgi-bin/xmlrpc.cgi

LSL Server Code

(上記の例に) 対応する LSL コードは以下の通りです。(オブジェクト内のスクリプトにコピー&ペーストし、保存し、rez してください。チャネル ID およびその他の情報がメッセージとして表示されます。) :

key remoteChannel;
init() {
    llOpenRemoteDataChannel(); // create an XML-RPC channel
    llOwnerSay("My key is " + (string)llGetKey());
}

default {
    state_entry() {
        init();
    }
    
    state_exit() {
        return;
    }
                                
    on_rez(integer param) {
        llResetScript();        
    }
                                
    remote_data(integer type, key channel, key message_id, string sender, integer ival, string sval) {
         if (type == REMOTE_DATA_CHANNEL) { // channel created
             llSay(DEBUG_CHANNEL,"Channel opened for REMOTE_DATA_CHANNEL" + 
                (string)channel + " " + (string)message_id + " " + (string)sender + " " +                         
                (string)ival + " " + (string)sval);
             remoteChannel = channel;
             llOwnerSay("Ready to receive requests on channel \"" + (string)channel + "\"");                        
             state receiving; // start handling requests
         } else {
             llSay(DEBUG_CHANNEL,"Unexpected event type"); 
         }                      
     }                 
}                     
                                

state receiving {

    state_entry() {
        llOwnerSay("Ready to receive information from outside SL");
    }  
    
    state_exit() {
        llOwnerSay("No longer receiving information from outside SL.");
        llCloseRemoteDataChannel(remoteChannel);
    }
    
    on_rez(integer param) {
        llResetScript();
    }
    
    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
             llSay(DEBUG_CHANNEL,"Request received for REMOTE_DATA_REQUEST " + (string)channel + " " +
                (string)message_id + " " + (string)sender + " " + (string)ival + " " + (string)sval);
            llRemoteDataReply(channel,NULL_KEY,"I got it",2008);
            llOwnerSay("I just received data in "+ llGetRegionName() + 
                        " at position " + (string)llGetPos() + "\n" +
                       "The string was " +  sval + "\nThe number was " + (string)ival + ".");
        }
    }
}