Difference between revisions of "LSL HTTP server/examples/ja"

From Second Life Wiki
Jump to navigation Jump to search
Line 5: Line 5:
=== Hello World! ===
=== Hello World! ===
古典的でシンプルな、可能な範囲でいちばん小さい http_request スクリプトです。
古典的でシンプルな、可能な範囲でいちばん小さい http_request スクリプトです。
<lsl>
<source lang="lsl2">
default
default
{
{
Line 25: Line 25:
     }
     }
}
}
</lsl>
</source>
もっと頑丈に作ったバージョン
もっと頑丈に作ったバージョン
<lsl>
<source lang="lsl2">
default
default
{
{
Line 55: Line 55:
     }
     }
}
}
</lsl>
</source>


=== Echo World ===
=== Echo World ===
"Echo World ([[User:Byrd Sciavo|Byrd Sciavo]] 04:19, 7 October 2009 (UTC))" は "Hello World" をもうちょっと使えるようにしたもので、動的に生成されたデータフィードを返す簡単なサーバのデモンストレーションになっています。Echo World は http_request がどのように GET で渡された変数を受け取るかを示しています。この「動的エコー」を受け取るために、以下のように、ご自分の URL の最後尾にクエリ文字列を追加してください。
"Echo World ([[User:Byrd Sciavo|Byrd Sciavo]] 04:19, 7 October 2009 (UTC))" は "Hello World" をもうちょっと使えるようにしたもので、動的に生成されたデータフィードを返す簡単なサーバのデモンストレーションになっています。Echo World は http_request がどのように GET で渡された変数を受け取るかを示しています。この「動的エコー」を受け取るために、以下のように、ご自分の URL の最後尾にクエリ文字列を追加してください。
https://sim3015.aditi.lindenlab.com:12043/cap/a7717681-2c04-e4ac-35e3-1f01c9861322/foo/bar?arg=gra
https://sim3015.aditi.lindenlab.com:12043/cap/a7717681-2c04-e4ac-35e3-1f01c9861322/foo/bar?arg=gra
<lsl>
<source lang="lsl2">
string url;
string url;
default
default
Line 77: Line 77:
     }
     }
}
}
</lsl>
</source>


=== 訪問者リスト ===
=== 訪問者リスト ===
Line 83: Line 83:
<br>注意:
<br>注意:
* このスクリプトには、リクエストしたデータの帰りを非同期で待ちながら、複数のリクエストをさばくメソッドが入っています。
* このスクリプトには、リクエストしたデータの帰りを非同期で待ちながら、複数のリクエストをさばくメソッドが入っています。
<lsl>integer scanning = FALSE;
<source lang="lsl2">integer scanning = FALSE;


list requests;
list requests;
Line 153: Line 153:
     }
     }
}
}
</lsl>
</source>


=== URL 固定 / ビジターカウンター ===
=== URL 固定 / ビジターカウンター ===
'hello world' をもっと完成に近づけたもので、常に URL をもち、訪問者をカウントし続けます。
'hello world' をもっと完成に近づけたもので、常に URL をもち、訪問者をカウントし続けます。
<lsl>
<source lang="lsl2">
string url;
string url;
integer hits;
integer hits;
Line 211: Line 211:
     }
     }
}
}
</lsl>
</source>




=== Perl/Python で POST を使った例 ===
=== Perl/Python で POST を使った例 ===
POST を使った他の例を示した一連のスクリプトです。最初のスクリプトはグリッドの情報を受信する LSL プログラムです。2 番目のスクリプトは Perl スクリプトで、外部サーバに置いてグリッドのプログラムと通信するのに使います。3 番目のスクリプトは Python スクリプトで、同じように外部サーバに置いてグリッドのプログラムと通信するのに使います。([[User:Grandma Bates|Grandma Bates]] 12:42, 27 May 2009 (UTC))
POST を使った他の例を示した一連のスクリプトです。最初のスクリプトはグリッドの情報を受信する LSL プログラムです。2 番目のスクリプトは Perl スクリプトで、外部サーバに置いてグリッドのプログラムと通信するのに使います。3 番目のスクリプトは Python スクリプトで、同じように外部サーバに置いてグリッドのプログラムと通信するのに使います。([[User:Grandma Bates|Grandma Bates]] 12:42, 27 May 2009 (UTC))
<lsl>
<source lang="lsl2">
key requestURL;
key requestURL;


Line 255: Line 255:
     }
     }
}
}
</lsl>
</source>


グリッド上のプリムと通信する Perl スクリプトです。
グリッド上のプリムと通信する Perl スクリプトです。
Line 345: Line 345:
POST を使った他の例を示した一連のスクリプトです。この例では、スクリプトは渡された引数を解釈するようになっています。最初のスクリプトはグリッドの情報を受信する LSL プログラムです。2 番目のスクリプトは Perl スクリプトで、外部サーバに置いてグリッドのプログラムと通信するのに使います。3 番目のスクリプトは Python スクリプトで、同じように外部サーバに置いてグリッドのプログラムと通信するのに使います。 ([[User:Grandma Bates|Grandma Bates]] 12:42, 27 May 2009 (UTC))
POST を使った他の例を示した一連のスクリプトです。この例では、スクリプトは渡された引数を解釈するようになっています。最初のスクリプトはグリッドの情報を受信する LSL プログラムです。2 番目のスクリプトは Perl スクリプトで、外部サーバに置いてグリッドのプログラムと通信するのに使います。3 番目のスクリプトは Python スクリプトで、同じように外部サーバに置いてグリッドのプログラムと通信するのに使います。 ([[User:Grandma Bates|Grandma Bates]] 12:42, 27 May 2009 (UTC))


<lsl>
<source lang="lsl2">
key requestURL;
key requestURL;


Line 410: Line 410:
     }
     }
}
}
</lsl>
</source>


対応する Perl スクリプトです。グリッド上のプリムと通信します。
対応する Perl スクリプトです。グリッド上のプリムと通信します。
Line 545: Line 545:
この例は Simba Fuhr が作成しました。
この例は Simba Fuhr が作成しました。
{{Warning|プロバイダによっては、fsockopen を標準のポート 80 または 443 でしか許可していないことがあります。このスクリプトはそのようなプロバイダ上で動作しません。}}
{{Warning|プロバイダによっては、fsockopen を標準のポート 80 または 443 でしか許可していないことがあります。このスクリプトはそのようなプロバイダ上で動作しません。}}
<lsl>
<source lang="lsl2">
default
default
{
{
Line 564: Line 564:
  }
  }
}
}
</lsl>
</source>


PHP スクリプトです。
PHP スクリプトです。

Revision as of 10:40, 21 February 2016

ユーティリティ・スクリプト

「穴埋め」練習に向いた、とってもとってもシンプルな HTTP サーバは、こちらです。 Utility Script

Hello World!

古典的でシンプルな、可能な範囲でいちばん小さい http_request スクリプトです。

default
{
    state_entry()
    {
        llRequestURL();
    }

    http_request(key id, string method, string body)
    {
        if (method == URL_REQUEST_GRANTED)
        {
            llSay(0,"URL: " + body);
        }
        else if (method == "GET")
        {
            llHTTPResponse(id,200,"Hello World!");
        }
    }
}

もっと頑丈に作ったバージョン

default
{
    state_entry()
    {
        llRequestURL();
    }

    http_request(key id, string method, string body)
    {
        if (method == URL_REQUEST_GRANTED)
        {
            llSay(0,"URL: " + body);
        }
        else if (method == URL_REQUEST_DENIED)
        {
            llSay(0, "Something went wrong, no url. " + body);
        }
        else if (method == "GET")
        {
            llHTTPResponse(id,200,"Hello World!");
        }
        else
        {
            llHTTPResponse(id,405,"Unsupported Method");
        }
    }
}

Echo World

"Echo World (Byrd Sciavo 04:19, 7 October 2009 (UTC))" は "Hello World" をもうちょっと使えるようにしたもので、動的に生成されたデータフィードを返す簡単なサーバのデモンストレーションになっています。Echo World は http_request がどのように GET で渡された変数を受け取るかを示しています。この「動的エコー」を受け取るために、以下のように、ご自分の URL の最後尾にクエリ文字列を追加してください。 https://sim3015.aditi.lindenlab.com:12043/cap/a7717681-2c04-e4ac-35e3-1f01c9861322/foo/bar?arg=gra

string url;
default
{
    state_entry(){
        llRequestURL();
    }

    http_request(key id, string method, string body){    
        if (method == URL_REQUEST_GRANTED) {
            url=body;llOwnerSay(url);
        }else if(method=="GET"){
              if(llGetHTTPHeader(id,"x-query-string")=="") llHTTPResponse(id,200,"I ECHO when you append some GET variables to me, e.g., /?var=foo");
              else llHTTPResponse(id,200,llGetHTTPHeader(id,"x-query-string"));
        }        
    }
}

訪問者リスト

サーバのセンサーの範囲内の人のリストです。
注意:

  • このスクリプトには、リクエストしたデータの帰りを非同期で待ちながら、複数のリクエストをさばくメソッドが入っています。
integer scanning = FALSE;

list requests;

send_response(string body)
{
    integer j;
    for (j = 0; j < llGetListLength(requests); ++j)
    {
        llHTTPResponse(llList2Key(requests,j), 200, body);
    }
    requests = [];
}

default
{
    state_entry()
    {
        llRequestURL();
    }
 
    http_request(key id, string method, string body)
    {
        if (method == URL_REQUEST_GRANTED)
        {
            llSay(0,"URL: " + body);
        }
        else if (method == URL_REQUEST_DENIED)
        {
            llSay(0, "Something went wrong, no url. " + body);
        }
        else if (method == "GET")
        {
            if (!scanning)
            {
                llSensor("",NULL_KEY,AGENT,96,PI);
                scanning = TRUE;
            }
            
            requests += [id];
        }
        else
        {
            llHTTPResponse(id,405,"Unsupported method.");
        }
    }
 
    no_sensor()
    {
        send_response("There is no one here.");
        scanning = FALSE;
    }
 
    sensor(integer n)
    {
        string output;
        if (n < 16) output = "There are " + (string)n + " avatars nearby:";
        else output = "There are at least 16 avatars nearby:";
        
        integer i;
        for (i = 0;i<n;++i)
        {
            output += "\n\t" + llDetectedName(i);
        }
        
        send_response(output);

        scanning = FALSE;
    }
}

URL 固定 / ビジターカウンター

'hello world' をもっと完成に近づけたもので、常に URL をもち、訪問者をカウントし続けます。

string url;
integer hits;

setup()
{
    llSetObjectName("HTTP Server");
    url = "";
    llRequestURL();
    hits = (integer)llGetObjectDesc();
    llSetText((string)hits + " visitors.",<1,1,0>,1);
}

default
{
    state_entry() { setup(); }
    on_rez(integer n) { setup(); }
    
    changed(integer c)
    {
        if (c & (CHANGED_REGION | CHANGED_REGION_START | CHANGED_TELEPORT) )
        {
            setup();
        }
    }
    
    touch_start(integer n)
    {
        llSay(0,"My url is: " + url);
    }
 
    http_request(key id, string method, string body)
    {
        if (method == URL_REQUEST_GRANTED)
        {
            url = body;
        }
        else if (method == URL_REQUEST_DENIED)
        {
            llSay(0, "Something went wrong, no url. " + body);
        }
        else if (method == "GET")
        {
            ++hits;
            llSetObjectDesc((string)hits);
            llSetText((string)hits + " visitors.",<1,1,0>,1);
            llHTTPResponse(id,200,"Hello!  You are visitor " + (string)hits + ".");
        }
        else
        {
            llHTTPResponse(id,405,"Method unsupported");
        }
    }
}


Perl/Python で POST を使った例

POST を使った他の例を示した一連のスクリプトです。最初のスクリプトはグリッドの情報を受信する LSL プログラムです。2 番目のスクリプトは Perl スクリプトで、外部サーバに置いてグリッドのプログラムと通信するのに使います。3 番目のスクリプトは Python スクリプトで、同じように外部サーバに置いてグリッドのプログラムと通信するのに使います。(Grandma Bates 12:42, 27 May 2009 (UTC))

key requestURL;

default
{

    state_entry() {
        requestURL = llRequestURL();     // Request that an URL be assigned to me.
    }
    
    
     http_request(key id, string method, string body) {
        
        if ((method == URL_REQUEST_GRANTED) && (id == requestURL) ){
            // An URL has been assigned to me.
            llOwnerSay("Obtained URL: " + body);
            requestURL = NULL_KEY;
        }
        
        
        else if ((method == URL_REQUEST_DENIED) && (id == requestURL)) {
            // I could not obtain a URL
            llOwnerSay("There was a problem, and an URL was not assigned: " + body);
            requestURL = NULL_KEY;
        }

        else if (method == "POST") {
            // An incoming message was received.
            llOwnerSay("Received information from the outside: " + body);
            llHTTPResponse(id,200,"Thank you for calling. All of our operators are busy.");
        }

        
        else {
            // An incoming message has come in using a method that has not been anticipated.
            llHTTPResponse(id,405,"Unsupported Method");
        }
    }
}

グリッド上のプリムと通信する Perl スクリプトです。

<perl>

  1. !/usr/bin/perl
  2. Routine to contact a script on the SL Grid using http server

use LWP; require HTTP::Request; use URI::Escape; use strict;


  1. #################################################
  2. Routine to send the information to the prim
  3. submitInformation($url,$information)

sub submitInformation{

   # First get the arguments.
   my $url = shift;
   my $information = shift;
   # Create the objects to be used to send out the HTTP request
   my $browser = LWP::UserAgent->new;
   my $request = HTTP::Request->new(POST => $url);
   # Set the encoding method and specify the information to be sent.
   $request->content_type('application/x-www-form-urlencoded');
   $request->content(uri_escape($information));
   # Send the request.
   my $response = $browser->request($request);
   # Return the information sent back
   return($response->content);

}


  1. Set the URL manually....

my $url = 'http://sim3015.aditi.lindenlab.com:12046/cap/d57a7c8b-3ace-3186-730a-f22fde870d48';

my $info = submitInformation

   ($url,'id=244195d6-c9b7-4fd6-9229-c3a8b2e60e81&name=M Linden');

print $info,"\n"; </perl>

上の Perl コードと同じことをする Python コードです。

<python>

  1. !/usr/bin/python

import urllib


  1. #################################################
  2. Routine to send the information to the prim
  3. submitInformation(url,information)

def submitInformation(url,parameters) :

   # Set the parameters to be sent.
   encodedParams =  urllib.urlencode(parameters);
   # Post the data.
   net = urllib.urlopen(url,encodedParams);
   # return the result.
   return(net.read());


if __name__ == "__main__":

   # Set the URL manually
   url = 'http://sim3015.aditi.lindenlab.com:12046/cap/d57a7c8b-3ace-3186-730a-f22fde870d48';
   # Define the parameters
   parameters = {'id':'244195d6-c9b7-4fd6-9229-c3a8b2e60e81',
                 'name':'M Linden'}
   # Pass the information along to the prim
   info = submitInformation(url,parameters);
   print(info);

</python>

引数解析を含む、Perl/Python で POST を使った例

POST を使った他の例を示した一連のスクリプトです。この例では、スクリプトは渡された引数を解釈するようになっています。最初のスクリプトはグリッドの情報を受信する LSL プログラムです。2 番目のスクリプトは Perl スクリプトで、外部サーバに置いてグリッドのプログラムと通信するのに使います。3 番目のスクリプトは Python スクリプトで、同じように外部サーバに置いてグリッドのプログラムと通信するのに使います。 (Grandma Bates 12:42, 27 May 2009 (UTC))

key requestURL;

// ###############################################
// Routine to parse a string sent through the 
// http server via post.
//       parsePostData(theMessage)
// Returns a strided list with stride length 2.
// Each set has the key and then its value.
list parsePostData(string message) {
    list postData = [];         // The list with the data that was passed in.
    list parsedMessage = llParseString2List(message,["&"],[]);    // The key/value pairs parsed into one list.
    integer len = ~llGetListLength(parsedMessage);

    while(++len) {          
        string currentField = llList2String(parsedMessage, len); // Current key/value pair as a string.

        integer split = llSubStringIndex(currentField,"=");     // Find the "=" sign
        if(split == -1) { // There is only one field in this part of the message.
            postData += [llUnescapeURL(currentField),""];  
        } else {
            postData += [llUnescapeURL(llDeleteSubString(currentField,split,-1)), llUnescapeURL(llDeleteSubString(currentField,0,split))];
        }
    }
    // Return the strided list.
    return postData ;
}

default {

    state_entry() {
        requestURL = llRequestURL(); // Request that an URL be assigned to me.
    }
    
    http_request(key id, string method, string body) {
         list incomingMessage;
        
        if ((method == URL_REQUEST_GRANTED) && (id == requestURL) ){
            // An URL has been assigned to me.
            llOwnerSay("Obtained URL: " + body);
            requestURL = NULL_KEY;
        }
        else if ((method == URL_REQUEST_DENIED) && (id == requestURL)) {
            // I could not obtain a URL
            llOwnerSay("There was a problem, and an URL was not assigned: " + 
                       body);
            requestURL = NULL_KEY;
        }
        else if (method == "POST") {
            // An incoming message was received.
            llOwnerSay("Received information form the outside: " + body);
            incomingMessage = parsePostData(body);
            llOwnerSay(llDumpList2String(incomingMessage,"\n"));

            llHTTPResponse(id,200,"You passed the following:\n" + 
                           llDumpList2String(incomingMessage,"\n"));

        }
        else {
            // An incoming message has come in using a method that has
            // not been anticipated.
            llHTTPResponse(id,405,"Unsupported Method");
        }
    }
}

対応する Perl スクリプトです。グリッド上のプリムと通信します。

<perl>

  1. !/usr/bin/perl
  2. Routine to contact a script on the SL Grid using http server

use LWP; require HTTP::Request; use URI::Escape; use strict;


  1. #################################################
  2. Routine to send the information to the prim
  3. submitInformation($url,$information)

sub submitInformation{


   my $url = shift;                   # First get the arguments.
   my $information = shift;
   my $browser = LWP::UserAgent->new;                # Create the object
   my $request = HTTP::Request->new(POST => $url);   # used to send the
                                                     # HTTP request
   $request->content_type                            # Set the

('application/x-www-form-urlencoded'); # encoding type.

   $request->content(hash2URI($information));        # Set the content to
                                                     # send.
   my $response = $browser->request($request);       # Send the request.
   return($response->content);                       # Return the

# information that # was sent back }


  1. #########################################################################
  2. Convert a hash to a url encoded string
  3. hash2URI(\%hash)

sub hash2URI {

   my $theHash = shift;            # Get the arguments passed.
   my $encodedString = ;         # The encoded string to return.
   my $lupe;                       # a loop variable.


   foreach $lupe (keys %{$theHash}) {                # 

$encodedString .= uri_escape($lupe) . '=' . # Add each item in the uri_escape($$theHash{$lupe}) . '&'; # hash to the encoded string.

   }
   $encodedString =~ s/&$//;                         # Remove the trailing "&"
   return($encodedString);                           # Send the encoded string.

}


  1. Set the URL manually....

my $url = 'http://sim3015.aditi.lindenlab.com:12046/cap/5a1b89cd-e681-8110-7245-fb98969f32a0';

my $info = submitInformation

   ($url,{'action' => 'send message',

'value'=> 'Hi there chief!', 'id'=>'244195d6-c9b7-4fd6-9229-c3a8b2e60e81', 'name'=>'M Linden'});

print($info,"\n");


</perl>


対応する Python スクリプトです。上の Perl スクリプトと同じことをします。

<python>

  1. !/usr/bin/python

import urllib import re

  1. #################################################
  2. Routine to send the information to the prim
  3. submitInformation(url,information)

def submitInformation(url,parameters) :

  1. encodedParams = urllib.urlencode(parameters); # encode the parameters
   encodedParams  = dictionary2URI(parameters);    # encode the parameters
   net = urllib.urlopen(url,encodedParams);        # Post the data.
   return(net.read());                             # return the result.



  1. ################################################
  2. Routine to encode a dictionary without using
  3. "+" for spaces.
  4. dictionary2URI(theDictionary)

def dictionary2URI(theDictionary) :

   encoded = ;           # Initialize the string to return
   for key, value in theDictionary.iteritems():
       # Encode each item in the dictionary.
       encoded += urllib.quote(key)+"="+urllib.quote(value)+"&";
   remove = re.compile('&$')             # Remove the trailing ampersand.
   encoded = remove.sub(,encoded);
   return(encoded);


if __name__ == "__main__":

   # Set the URL manually
   url = 'http://sim3015.aditi.lindenlab.com:12046/cap/5a1b89cd-e681-8110-7245-fb98969f32a0';
   # Define the parameters
   parameters = {'id':'244195d6-c9b7-4fd6-9229-c3a8b2e60e81',
                 'name':'M Linden',
                 'action':'send message',
                 'value':'Hey there, hi there, ho there!'};
   # Pass the information along to the prim
   info = submitInformation(url,parameters);
   print(info);

</python>

<lsl></lsl>


PHP を通して LSL にデータを送信する簡単なスクリプト

この例は Simba Fuhr が作成しました。

Warning!

プロバイダによっては、fsockopen を標準のポート 80 または 443 でしか許可していないことがあります。このスクリプトはそのようなプロバイダ上で動作しません。

default
{
 state_entry()
 {
  llRequestURL();
 }
 http_request(key id, string method, string body)
 {
  if ((method == URL_REQUEST_GRANTED))
  {
   llOwnerSay("URL: " + body);
  }
  else if (method == "POST")
  {
   llHTTPResponse(id, 200, body + " there !");
  }
 }
}

PHP スクリプトです。 LSL スクリプトに "Hello" と送信し、" there !" を付け加えて返却します。つまり、PHP は "Hello there !" と返すことになります。

<php> <?php $Data = CallLSLScript("http://sim3015.aditi.lindenlab.com:12046/cap/5a1b89cd-e681-8110-7245-fb98969f32a0", "Hello"); die($Data);

//Function by Simba Fuhr //Use under the GPL License function CallLSLScript($URL, $Data, $Timeout = 10) {

//Parse the URL into Server, Path and Port
$Host = str_ireplace("http://", "", $URL);
$Path = explode("/", $Host, 2);
$Host = $Path[0];
$Path = $Path[1];
$PrtSplit = explode(":", $Host);
$Host = $PrtSplit[0];
$Port = $PrtSplit[1];

//Open Connection
$Socket = fsockopen($Host, $Port, $Dummy1, $Dummy2, $Timeout);
if ($Socket)
{
 //Send Header and Data
 fputs($Socket, "POST /$Path HTTP/1.1\r\n");
 fputs($Socket, "Host: $Host\r\n");
 fputs($Socket, "Content-type: application/x-www-form-urlencoded\r\n");
 fputs($Socket, "User-Agent: Opera/9.01 (Windows NT 5.1; U; en)\r\n");
 fputs($Socket, "Accept-Language: de-DE,de;q=0.9,en;q=0.8\r\n");
 fputs($Socket, "Content-length: ".strlen($Data)."\r\n");
 fputs($Socket, "Connection: close\r\n\r\n");
 fputs($Socket, $Data);
  
 //Receive Data
 while(!feof($Socket))
  {$res .= fgets($Socket, 128);}
 fclose($Socket);
}
 
//ParseData and return it
$res = explode("\r\n\r\n", $res);
return $res[1];

} ?> </php>

Kelly のけったいな Web ステータス更新装置

原文のページにあります: Kelly's Stupid Web Status Updater
Kurai さんが改変したもの: Kurai's Stupid Web Status Updater Mod

グリッド URL 不揮発化のサンプルスクリプト

このスクリプト は、フリーのWeb サービス Grid URL Persister を使って、LSL HTTP サーバの一時的な URL を管理しています。

Web ベースの動的建築

HTTP-in は Web ページからインワールドのオブジェクトに簡単にコマンドを送るのに使用できます。つまり、Web のユーザが建築物をコントロールして情報をやりとりすることができます。Chromutate というインタラクティブな展示物は、このアイデアをもとにしています。フリーのスクリプトと詳細な説明は、 資料サイト を参照してください。

PHP/SQL オブジェクト DNS

PHP で書かれた簡単な DNS サーバです。LSL スクリプトで DNS サービスを扱いやすくします。 PHPDNS