Object to object HTTP communication

From Second Life Wiki
Jump to navigation Jump to search

This script allows you to communicate between objects without using an external server. It is a much simplified version of the communication system used by SLGI Trains and SLGI Fleet in case of emergency. I found it to be less lag then communications to outside servers, but still it might create some problems. So, try not to send more then 10 messages per second.

Basics

There are two scripts. The first one, named GIVE, is sending messages. The second one, RECEIVE, is the receiver. Place each one in a different object, but not too far, for the first moments.

Then, touch the object containing RECEIVE. It will say in chat the http and the url that GIVE will need to use. GIVE will listen those things, on channel 88225.

Then, touch GIVE anytime you want. It will send a message to RECEIVE. Now, you can take, wear or rezz GIVE wherever you need.

Limitations

This communication method has some major problems. You are unable to send a string from GIVE to RECEIVE. What you can do, is to send some limited information, that can be read with llGetHTTPHeader, like object position, object name and a few other features. Also, since URLs are temporary, it is very hard (nearly impossible) to communicate to an object that crosses sim borders.

As long as no url has dropped, communication channel is safe. I sent 30 test messages and all of them reached the target.

The code

GIVE code is:

//Created by Ana Imfinity
integer KANAL = 88225; 
//communication channel used by the two scripts
string url; 
string body; 
key req; 
default
{
    state_entry()
    {
        llListen(KANAL,"","",""); 
    }
    touch_start(integer ana) //this sends a message on touch
    {
        key aaa = llHTTPRequest(body,[],text); 
        llReleaseURL(body); 
    }
    listen(integer ch, string nm, key id, string ms) //this allows GIVE to get http & url codes
    {
        string dict = llGetSubString(ms,0,3); 
        string exec = llGetSubString(ms,4,100); 
        if (dict == "<><>")
        {
            url = (key)(exec); 
        }
        else if (dict == "><><")
        {
            body = exec; 
            llSay(0,"HTTP communication is now possible"); 
        }
    }
}

RECEIVE code is

//Created by Ana Imfinity
key url; 
string http; 
integer KANAL = 88225; 
default
{
    state_entry()
    {
    }
    touch_start(integer ana) //this sends the URL & http addresses to GIVE
    {
        llReleaseURL(http); 
        url = llRequestURL(); 
        llSay(0,"URL transmitted"); 
    }
    http_request(key req, string met, string body)
    {
        if (req == url) //this gets RECEIVE's url & http addresses
        {
            http = body; 
            string t4 = "<><>"+(string)(url); 
            string t5 = "><><"+body; 
            llSay(KANAL, t4); 
            llSleep(1); 
            llSay(KANAL, t5); 
        }
        string head = llGetHTTPHeader(req,"x-secondlife-region"); //the next part receives info from GIVE
        string name = llGetHTTPHeader(req,"x-secondlife-object-name"); 
        llSay(0,head); 
        llSay(0,name); 
    }
}

There are two HTTP headers that can be useful.

x-secondlife-region tells in what sim at at what global coordinates GIVE is located. By using llGetSubString you can separate the sim name from coordinates.

x-secondlife-object-name tells object's name. This is very useful. By using llSetLinkPrimitiveParams you can set the name of the prim hosting the script. Actually, object's name is not important, just the name of the prim hosting GIVE. Take a look at the following example:

{
    state_entry()
    {
        llSetTimerEvent(100); 
    }
    timer()
    {
        vector pos = llGetPos() + llGetRegionCorner(); 
        string text = (string)(pos); 
        float x = pos.x; 
        float y = pos.y; 
        float z = pos.z; 
        integer xx = (integer)(x); 
        integer yy = (integer)(y); 
        integer zz = (integer)(z); 

        string name = nm+"<"+(string)(xx)+","+(string)(yy)+","+
        (string)(zz)+">"; 
        llSetLinkPrimitiveParams(LINK_THIS,[PRIM_NAME,name]); 
        key aaa = llHTTPRequest(body,[],text); 
        llReleaseURL(body); 

//the string 'nm' is a string made of a few letters, encrypting vehicle's name, if it is on schedule, if it has passengers and other details.

Lifetime

If the object containing an URL crosses a sm border, the URL is lost. So, it is almost impossible to keep contact between two objects wandering throughout the grid. RECEIVE must be fixed.

Sim restart processes will disable any existing URL.

See also

llGetHTTPHeader - a way to decode inworld HTTPs

llHTTPRequest - makes a script listen to HTTPs

llHTTPResponse - send a HTTP

http_request & http_response - events, needed by the functions

LSL HTTP server - a good place to start learning

LSL HTTP server/examples - many useful examples