XML-RPC(4) PHPソース

harayoki

2007年05月08日 05:42


XML-RPC links


前回のエントリーでwebページとSL内のオブジェクトとの連携が取れた事を書きました。


カンバン作り直しました。

そもそもこのアイテム何?と、いう人は(1)のエントリーから読んでみてください。

というわけで、このエントリーでは、サーバ側に用意したPHPのソースコードを公開します。
lslソースコードよりも先に公開になってしまったので、
順番的にわかりづらいかも知れませんが、
セカンドライフにおいてXML-RPCを扱う場合は、
このようなサーバ側のプログラムを用意すればいいんだな~とでも
感じてもらえればいいと思います。


◆まず基礎知識

SLのXML-RPCの窓口はこのURLです。
xmlrpc.secondlife.com/cgi-bin/xmlrpc.cgi

やりとりするXMLは、このようなフォーマット形式となっています。
<xml version="1.0"?>
<methodCall>
<methodName>llRemoteData</methodName>
<params>
<param>
<value>
<struct>
<member><name>Channel</name><value><string>チャンネルキー</string></value></member>
<member><name>IntValue</name><value><int>数値</int></value></member>
<member><name>StringValue</name><value><string>文字列</string></value></member>
</struct>
</value>
</param>
</params>
</methodCall>

通信チャンネルのキー値整数文字列(253?バイトまで)の3つしか引数はありません。
◆ソース内容をかいつまんで解説。

・1つのphpファイルで、フォーム情報入力ページと
XML-RPC処理結果表示ページを出し分けます。

・phpファイルのアクセス時にGETでkey値が渡されると
それをデフォルトのチャンネルキーの値として使います

・フォーム情報送信前に最低限の内容チェックをjavascriptで行います。

・結果表示モード…と書いてあるコメントの下あたりで
XML-RPCの引数となるXMLを作成しています。
(正しくはxmlrpcmsgオブジェクトのインスタンスを作成している。)

・SLとPHPの通信時、サーバに接続できない場合と、
引数に間違いがある場合などにはエラーメッセージが表示されます。
それ以外を通信成功とみなします。
lslからの応答値は特にチェックしていません。

・ニュース表示メッセージの作成ロジックは
lsl側とPHP側両方に記述されてしまっています。
(lsl側のソースコード公開はまた次回)
これはあまりよろしくない例です。

lslは低レベルのプログラムしか書くことができないので
文字列操作などはPHPやperl,ruby,pythonなど、
サーバ側にまかせきってしまった方が良いと思います。
その方が段違いで楽です。

これは以前作った楽天CD検索マッシュアップサンプルでも同じです。
ロジックは可能ならばlsl以外に記述。

◆phpソース
別途xmlrpc.incが必要です。 http://phpxmlrpc.sourceforge.net
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>XML-RPC test</title>
<link href="rpcTest.css" type="text/css" rel="stylesheet" />
<script>
//フォームの内容が正しければ送信
function checkAndSend() {
try {
var channelkey = document.getElementById('channelkey');
var stringMessage = document.getElementById('stringMessage');
var yourName = document.getElementById('yourName');
if(yourName.value=="") yourName.value="ななし";
if(channelkey.value==""){
showStatus("Channel keyを記述してください");
return;
}
if(stringMessage.value==""){
showStatus("ニュース内容を記述してください");
return;
}
var form = document.getElementById("formarea");
form.submit();
} catch (err) {
showStatus("ニュースの配信に失敗しました。"+err.message);
return;
}
}
//エラーメッセージなどを表示する
function showStatus(s){
var el = document.getElementById("statusText");
el.innerHTML = s;
}
</script>
</head>
<body>
<div class="input">
<h1>オラニュース ブロードキャスター ver2.03</h1>
<?php
$thisURL = $_SERVER['PHP_SELF'];
if (($_POST['action'])=="post") {

/******** 結果表示モード ********/

$yourName = htmlspecialchars($_POST['yourName']);
$channelkey = htmlspecialchars($_POST['channelkey']);
$stringMessage = htmlspecialchars($_POST['stringMessage']);

include 'xmlrpc.inc';
$GLOBALS['xmlrpc_internalencoding']='UTF-8';

$server = new xmlrpc_client('/cgi-bin/xmlrpc.cgi','xmlrpc.secondlife.com', 80);
$struct = array();
$struct['Channel']=new xmlrpcval($channelkey,'string');
$struct['IntValue']=new xmlrpcval('0','int');
$struct['StringValue']=new xmlrpcval($yourName."さんは本日未明、".$stringMessage);
$message = new xmlrpcmsg(
'llRemoteData',array(new xmlrpcval($struct,'struct'))
);
$result = $server->send($message);

/******** SLからの応答 戻り値は未チェック ********/

if (!$result) {
print "<span class='error'>サーバにアクセス出来ませんでした</span>";
} elseif ($result->faultCode()) {
print "<span class='error'>XML-RPC 失敗 ". $result->faultCode()." : ".$result->faultString()."</span>";
} else {
print <<< DOC_END
<h2>以下の内容でニュースを配信しました</h2>
<ul class='sendvalue'>
<li>送信者:$yourName</li>
<li>チャンネル:$channelkey</li>
<li>ニュース内容:$stringMessage</li>
</ul>
<a href='$thisURL'>戻る</a>";
DOC_END;
}

}else{

/******** 投稿モード ********/

$defaultKey = "c13afed1-0170-9868-939e-15d981c0b1c8";
if (isset($_GET['key'])) $defaultKey = $_GET['key'];
print <<< DOC_END
<form method="post" action="$thisURL" id="formarea">
<h2>Channel key:</h2>
<input type='text' id='channelkey' name='channelkey' size='40' maxlength='50' value='$defaultKey' />
<h2>あなたの名前</h2>
<input type='text' id='yourName' name='yourName' size='40' maxlength='50' value='' />
<h2>あなたの最近のニュース</h2>
<input type='text' name='stringMessage' id='stringMessage' name='stringMessage' size='40' maxlength='255' value='' />
<div class="example">例) 通勤中に道端で100円を拾った、朝食のお茶の中に茶柱が立った、大好きな彼氏とケンカした、etc..</div>
<input type='hidden' id='action' name='action' value='post'>
<input type='button' value="ニュースを配信!" class="button" />
</form>
DOC_END;
}
?>

</div>
<div id="statusText" class="status"></div>

</body>
</html>


と、こんな感じでした。

ニュースメッセージ作成処理部分は修正予定なので、
その際にこのマイク富丘さんは、
もっと楽しいいわゆるジェネレータ的なアイテムに改造してみようかと思います。
マイク富丘2世をお楽しみに!?

--

さてさて、自分はサーバ側のプログラミング作成は専門ではないので
PHPを用いたXML-RPCを使った作例を作るにあたっては、
下記サイトを大いに参考にしました。

基本的な情報はここで。
XML-RPC HOWTO PHP での XML-RPC の使い方

まさに日本語のメッセージが送信できなかったのでその対処方法はここで。
PHPのテクメモ xmlrpc.incで日本語が通らない

struct型の引数の作り方もここで。
PHPのテクメモ XML-RPCによるブログ操作のサンプル

いやはや、webってすばらしいですね。
マイク富丘(RPC)