User:Fred Rookstown/2WayLSLToViewerComms
This page shall contain analyses and protocol proposals for 2-way script/viewer communications, in an attempt to improve communications between scripts and viewers.
Feel free to add in your own thoughts and suggestions. I am also willing to host an "office hour" sort of thing at my lounge in Nolan if you wish to discuss this face-to-face with others in a realtime environment.
Why?
In this age of OpenSource viewers, problems begin to crop up as viewers are modified to support additions to the client code that would not be possible via LSL, such as fast, reliable client-side radars and client-side BDSM restraints. One of the most major issues encountered by developers is the transmission of data back and fourth between LSL and the client itself. Although several methods exist, they can prove to inadequate. In addition, since no current standard of communication currently exists for reliable client<-> server communications, developers wishing to integrate their products with the client must go through a trial and error process in order to find the best solution, and even then, the solution may not be a reliable communications channel.
In addition, 2-way variable communications between LSL and client-side scripts (like Lua, being developed in the Emerald viewer) would open a gigantic new realm of possibilities in SL content creation that would not be possible with the current methods.
This wiki page aims to propose a reliable, simple-to-use method of sharing data between server-side LSL and the client itself.
Communications methods
Since I am by no means an expert at messing with the SL client, feel free to correct me if you feel I am wrong with any point.
LLMessageSystem
The method LL uses to share information with their servers is via the LLMessageSystem class, which sends and receives raw TCP or UDP packets from the servers and deciphers them into a manageable format. It also performs automatic bandwidth throttling.
Pros:
- LLMessageSystem is the most direct way of talking to the sim server, which is where the scripts run.
- Relatively easy to use
- Already in place
- Automatically (de)serializes data as it's sent; Little to no typecasting required.
- Totally transparent to the user
Cons:
- Would require a message.xml change to implement a new message type, and on both ends (servers and viewer)
- Would require new LSL communications functions.
- Not necessarily the most reliable method.
- WOuld require a new capability to notify the server that the channel sharing code is available.
HTTP Client/Server
HTTP transmissions to and form the client and servers. Could be XMLRPC, REST, or just plain HTTP.
Pros:
- Somewhat fast, although it depends on application and workload.
- More reliable than LLMessageSystem
- Basic classes in place.
- Can send many datatypes.
- Can send a large volume of data.
Cons:
- More overhead than LLMessages.
- Would require operation of an HTTP server on the client to be able to share data to the client, would be difficult to access behind a NAT/Firewall (polling the server would lag the client and server to death).
- Would require significant LL-side changes to be able to handle HTTP data faster.
- Raw HTTP requires significant data processing in order to convert from the request/response to client-accessible data, many typecasting operations to handle, including unicode.
Chat
Chat communications is currently used by RestrainedLife and PAR/Emerald RadarChat, in order to convey information back and forth between the script and viewer.
Pros:
- Always in place.
- Can both send and receive data through NATs and firewalls.
- Simple to send data.
Cons:
- Requires the reservation of a channel for use with the component.
- Malicious/false data can be sent more easily than other methods.
- 1024 character limit, restricting size.
- Not reliable at all; Even minor lag can seriously affect communications.
- Easy for users to identify an open channel; Just listen on the chat channel. Bad for vendors and privacy in general.
Jabber/XMPP
From XMPP.org:
- The Extensible Messaging and Presence Protocol (XMPP) is an open technology for real-time communication, which powers a wide range of applications including instant messaging, presence, multi-party chat, voice and video calls, collaboration, lightweight middleware, content syndication, and generalized routing of XML data. The technology pages provide more information about the various XMPP "building blocks". Several books about Jabber/XMPP technologies are available, as well.
Pros:
- Open source
- Well-known protocol
- Has documented standards
- Scalable (Decentralized, used in Google Talk)
- May shoehorn in long-overdue group chat fixes.
Cons:
- Requires implementation on both the servers and client.
- LL has already deemed XMPP-based messaging services too immature to implement.
- May require significant code changes to handle XMPP safely and securely.
- Additional libraries required on both servers and client
- Licensing may be an issue.
LSL methods
What I am considering, for LSL, is the addition of functions to establish, maintain, and terminate a data sharing channel. A script would request a channel to a service on a particular agent (normally the owner but may be otherwise in other applications), and, if the server has been notified via CAPS (on login) that the agent has datashare channels, and that the specific service has been registered on that channel, the server will tell the script to go ahead with the operation (via an event or return value). The script then receives the client's shared variables, and the script can register its own shared variables.
<lsl> integer datashare; // Resource pointer to the channel.
default {
state_entry() { datashare = llRequestDatashare(llGetOwner(),"Radar",0); // 3rd option is a service version requirement. 0 means any version, non-zero means that the server will check if the service is at least that version before allowing it. }
datashare(integer datashare_pointer,integer update_type) { if(update_type==DATASHARE_AVAILABLE && datashare==datashare_pointer) { llShareString(datashare,"ScriptRegion",llGetRegionName()); // 3rd argument can be left blank to receive the contents of the variable. }
// Sent when the viewer has changed something in the channel.
if(update_type==DATASHARE_CHANGED && datashare==datashare_pointer) { llSay(0,"Viewer channel: "+llShareString(datashare,"ViewerChannel","")); } }
} </lsl>
Functions/Keywords to Implement
I'm planning on implementing Datashares on OpenSim during the summer. The following is an LSL-side roadmap.
- Datashare Management
- Datashare variables
Implementations
The Emerald viewer uses a variant of this (called GreenLife Utility Streams).