RestConsole
From OpenSimulator
(Example for JavaScript/HTML) |
m (→JavaScript/HTML: Added some whitespace for better readability) |
||
Line 105: | Line 105: | ||
<html> | <html> | ||
<head> | <head> | ||
+ | |||
<!-- This JavaScript code is published by Marck (c) 2010 under a --> | <!-- This JavaScript code is published by Marck (c) 2010 under a --> | ||
<!-- Creative Commons Attribution 3.0 Germany License --> | <!-- Creative Commons Attribution 3.0 Germany License --> | ||
<!-- http://creativecommons.org/licenses/by/3.0/de/ --> | <!-- http://creativecommons.org/licenses/by/3.0/de/ --> | ||
<script type="text/javascript"> | <script type="text/javascript"> | ||
+ | |||
var sessionId; | var sessionId; | ||
var hostUrl; | var hostUrl; | ||
+ | |||
function StartSession(url, user, password) { | function StartSession(url, user, password) { | ||
hostUrl = url; | hostUrl = url; | ||
Line 116: | Line 119: | ||
sessionId = response.getElementsByTagName("SessionID")[0].firstChild.nodeValue; | sessionId = response.getElementsByTagName("SessionID")[0].firstChild.nodeValue; | ||
}; | }; | ||
+ | |||
function ReadResponses() { | function ReadResponses() { | ||
var response = this.SendRequest("/ReadResponses/" + sessionId + "/", ''); | var response = this.SendRequest("/ReadResponses/" + sessionId + "/", ''); | ||
Line 126: | Line 130: | ||
document.getElementById("output").scrollTop = document.getElementById("output").scrollHeight; | document.getElementById("output").scrollTop = document.getElementById("output").scrollHeight; | ||
}; | }; | ||
+ | |||
function Command(cmd) { | function Command(cmd) { | ||
void SendRequest("/SessionCommand/", "ID=" + sessionId + "&COMMAND=" + cmd); | void SendRequest("/SessionCommand/", "ID=" + sessionId + "&COMMAND=" + cmd); | ||
}; | }; | ||
+ | |||
function CloseSession() { | function CloseSession() { | ||
void SendRequest("/CloseSession/", "ID=" + sessionId); | void SendRequest("/CloseSession/", "ID=" + sessionId); | ||
}; | }; | ||
+ | |||
function SendRequest(path, data) { | function SendRequest(path, data) { | ||
var request = new XMLHttpRequest(); | var request = new XMLHttpRequest(); | ||
Line 138: | Line 145: | ||
return request.responseXML; | return request.responseXML; | ||
}; | }; | ||
+ | |||
window.onunload = CloseSession; | window.onunload = CloseSession; | ||
+ | |||
</script> | </script> | ||
</head> | </head> | ||
<body> | <body> | ||
+ | |||
<form action="#" onsubmit=" | <form action="#" onsubmit=" | ||
StartSession(this.address.value, this.user.value, this.password.value); | StartSession(this.address.value, this.user.value, this.password.value); | ||
Line 151: | Line 161: | ||
<input type="submit" value="Login" /> | <input type="submit" value="Login" /> | ||
</form> | </form> | ||
+ | |||
<div id="output" style="height:15em; border:thin solid; overflow:auto;"></div> | <div id="output" style="height:15em; border:thin solid; overflow:auto;"></div> | ||
+ | |||
<form action="#" onsubmit=" | <form action="#" onsubmit=" | ||
Command(this.command.value); | Command(this.command.value); | ||
Line 159: | Line 171: | ||
<input type="submit" value="Send Command" /> | <input type="submit" value="Send Command" /> | ||
</form> | </form> | ||
+ | |||
</body> | </body> | ||
</html> | </html> | ||
</pre> | </pre> |
Revision as of 04:35, 4 September 2010
Contents |
About
The REST console makes remote administration of the various OpenSim services possible.
The interface allows sending commands to the server and retrieving command output. Sending and receiving data is done through RESTful HTTP calls.
While sending is very straightforward, receiving is not. Receiving uses reverse HTTP, performing a long poll to a CAPS URI.
In order to make the protocol more efficient, the help functionality has been pushed to the client side. Rather than sending each keystroke to the server, only validated command lines are sent. To make this possible, the server sends a "connect burst" of data, which is the tree of allowed commands and their help information. This can be used by the client to create the "help" command output locally as well as provide command line help interactively.
The sample console client, OpenSim.ConsoleClient.exe, shows how this is done.
Syntax
We take the user service (http://foo.bar:8002) as example here. Start up the user service with:
mono OpenSim.Grid.UserServer.exe -console rest
First start a new session by sending a HTTP POST request. User name and password should match the settings for ConsoleUser and ConsolePass in section [Network] of OpenSim.ini.
Parameters: USER, PASS
http://foo.bar:8002/StartSession/
Return: (XML) <ConsoleSession><SessionID></SessionID><Prompt></Prompt></ConsoleSession>
Now we got the SessionID, which can be used to send a command and to receive output. First, retrieve the console scrollback buffer.
Parameters: none
http://foo.bar:8002/ReadResponses/<SessionID>/
Return: (XML) <ConsoleSession><Line Number=x></Line></ConsoleSession>
The reply contains all lines currently in the buffer. Subsequent fetches will only retrieve new lines. The fetch will hold for up to 30 seconds if there is no data, then return an error. The client is expected to try again (polling).
Use the SessionID as ID parameter, and send a POST request again.
Parameters: ID, COMMAND
http://foo.bar:8002/SessionCommand/
Return: (XML) <ConsoleSession><Result></Result></ConsoleSession>
If everything went well, the command should have been executed. Try another command.
When you want to close down the connection, send a POST request again.
Parameters: ID
http://foo.bar:8002/CloseSession/
Return: (XML) <ConsoleSession><Result></Result></ConsoleSession>
The session is closed, and you have to log in again, when you want to send a command again.
Examples
Python
#!/usr/bin/python # This piece of code is published by thomax (txOh) (c) 2010 under the # Artistic License 1.0 (http://www.perlfoundation.org/artistic_license_1_0) import urllib, urllib2 import xml.dom.minidom class UserConsoleClient(): def __init__(self, addr): self.addr = addr url = self.addr + 'StartSession/' params = urllib.urlencode({ 'USER': 'Test', # REST username 'PASS': 'secret' # REST password }) data = urllib2.urlopen(url, params).read() dom = xml.dom.minidom.parseString(data) elem = dom.getElementsByTagName('SessionID') self.sessionid = elem[0].childNodes[0].nodeValue def close(self): url = self.addr + 'CloseSession/' params = urllib.urlencode({ 'ID': self.sessionid }) print urllib2.urlopen(url, params).read() def do_cmd(self, cmd): url = self.addr + '/SessionCommand/' params = urllib.urlencode({ 'ID': self.sessionid, 'COMMAND': cmd }) print urllib2.urlopen(url, params).read() def read_buffer(self): url = self.addr + 'ReadResponses/' + self.sessionid + '/' params = urllib.urlencode({ 'ID': self.sessionid }) print urllib2.urlopen(url, params).read() # set the base url to the REST console (with port) console = UserConsoleClient('http://127.0.0.1:8300/') console.read_buffer() print 'quit with a "."' cmd = "" while cmd != ".": if cmd != "": console.do_cmd(cmd) console.read_buffer() cmd = raw_input("> ") console.close()
JavaScript/HTML
<html> <head> <!-- This JavaScript code is published by Marck (c) 2010 under a --> <!-- Creative Commons Attribution 3.0 Germany License --> <!-- http://creativecommons.org/licenses/by/3.0/de/ --> <script type="text/javascript"> var sessionId; var hostUrl; function StartSession(url, user, password) { hostUrl = url; var response = SendRequest("/StartSession/", "USER=" + user + "&PASS=" + password); sessionId = response.getElementsByTagName("SessionID")[0].firstChild.nodeValue; }; function ReadResponses() { var response = this.SendRequest("/ReadResponses/" + sessionId + "/", ''); var lines = response.getElementsByTagName("Line"); for (var i = 0; i < lines.length; ++i) { var element = document.createElement("div"); element.appendChild(document.createTextNode(lines[i].firstChild.nodeValue)); document.getElementById("output").appendChild(element); }; document.getElementById("output").scrollTop = document.getElementById("output").scrollHeight; }; function Command(cmd) { void SendRequest("/SessionCommand/", "ID=" + sessionId + "&COMMAND=" + cmd); }; function CloseSession() { void SendRequest("/CloseSession/", "ID=" + sessionId); }; function SendRequest(path, data) { var request = new XMLHttpRequest(); request.open("POST", hostUrl + path, false); request.send(data); return request.responseXML; }; window.onunload = CloseSession; </script> </head> <body> <form action="#" onsubmit=" StartSession(this.address.value, this.user.value, this.password.value); ReadResponses(); return false"> <input name="address" type="text" value="http://localhost:9000" /> <input name="user" type="text" value="ConsoleUser" /> <input name="password" type="text" value="ConsolePass" /> <input type="submit" value="Login" /> </form> <div id="output" style="height:15em; border:thin solid; overflow:auto;"></div> <form action="#" onsubmit=" Command(this.command.value); ReadResponses(); return false"> <input type="text" name="command" value="Enter command here" size="40"/> <input type="submit" value="Send Command" /> </form> </body> </html>