RestConsole/de
From OpenSimulator
Contents |
Über
Die REST-Konsole macht Remote-Administration der verschiedenen Open Dienste möglich.
Die Schnittstelle ermöglicht Befehle an den Server und Abrufen von Befehlsausgabe zu senden. Senden und Empfangen von Daten über RESTful HTTP-Aufrufe erfolgen.
Während das Senden sehr einfach ist, wird nicht mit. Empfangen verwendet HTTP-Reverse, eine lange Umfrage zu einer CAPS URI durchführen.
Um das Protokoll effizienter zu gestalten, die Hilfefunktion zu machen wurde auf der Client-Seite geschoben. Anstatt jeden Tastendruck an den Server senden, werden nur validierte Befehlszeilen gesendet. Um dies möglich zu machen, sendet der Server eine Burst-on-Connect von Daten, die der Baum der erlaubten Befehle und deren Hilfeinformationen. Dies kann durch den Kunden verwendet werden, um die "Hilfe" Befehlsausgabe sowohl lokal als auch zu schaffen als Kommandozeilen-Hilfe interaktiv zur Verfügung stellen.
Die Probe Konsolen-Client, OpenSim.ConsoleClient.exe, zeigt, wie das gemacht wird.
Verwendung
Um die Remote - Konsole zu verwenden, starten Sie Open Dienste mit dem Parameter -console rest.
Beispiel für Robust-Server im Grid-Modus:
mono Robust.exe -console rest
Beispiel für Simulatoren (sowohl im Grid und Standalone-Modus):
mono OpenSim.exe -console rest
Syntax
Wir nehmen den Opensimulator Dienstleistungsadresse http://foo.bar:8002 als Beispiel.
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()
Python (Updated)
#!/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) # Modifications (c) 2013 BlueWall import urllib, urllib2 import xml.dom.minidom class UserConsoleClient(): def __init__(self, addr): self.addr = addr url = self.addr + 'StartSession/' params = urllib.urlencode({ 'USER': 'username', # REST username 'PASS': 'userpass' # REST password }) data = urllib2.urlopen(url, params).read() print data dom = xml.dom.minidom.parseString(data) elem = dom.getElementsByTagName('SessionID') self.sessionid = elem[0].childNodes[0].nodeValue elem = dom.getElementsByTagName('Prompt') self.prompt = 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 }) data = urllib2.urlopen(url, params).read() dom = xml.dom.minidom.parseString(data) elem = dom.getElementsByTagName('Result') return elem[0].childNodes[0].nodeValue def read_buffer(self): url = self.addr + 'ReadResponses/' + self.sessionid + '/' params = urllib.urlencode({ 'ID': self.sessionid }) # print urllib2.urlopen(url, params).read() result = urllib2.urlopen(url, params).read() dom = xml.dom.minidom.parseString(result) elem = dom.getElementsByTagName('Line') for line in elem: x0 = line.childNodes[0].nodeValue x1 = str.replace(str(x0),':','~',2) x2 = x1.split("~") for lv in x2[2:]: if not '+++' in lv: print lv # set the base url to the REST console (with port) console = UserConsoleClient('http://example.com:8003/') console.read_buffer() print 'quit with a "."' cmd = "" while cmd != ".": if cmd != "": if 'OK' in console.do_cmd(cmd): console.read_buffer() cmd = raw_input("%s " % console.prompt) 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>