Ich habe mich mit alternativen zu SOAP beschäftigt. Was meiner Meinung nach auch sehr gut für IP-Symcon in Frage kommen würde ist eine JSON-Schnittstelle.
Vorteile dafür wären beispielsweise:
[ul]
[li]Die Funktionen von IPS können so genutzt werden, wie sie in den Befehlsrefenzen angegeben werden (http://www.ip-symcon.de/service/dokumentation/befehlsreferenz/)[/li][li]Schnelle Integrations ins Webfront[/li][li]Bereits vorhandene Möglichkeit zur User-Auth (Webfront Login)[/li][li]Sehr schnelle Replys mit wenig Daten-Overhead. Besonders gut geeignet für dünne Leitungen (wie z.B. UMTS, HSDPA usw…)[/li][/ul]
Einen initialen Wrapper dafür habe ich mal geschrieben. Dieser muß lediglich im Webfront plaziert werden. Weitere Anpassungen sind nicht nötig.
<?php
ini_set('display_errors', 1);
ini_set('error_reporting', E_ERROR);
$postdata = $GLOBALS['QUERY_STRING'];
$request = json_decode($postdata);
// Check if the request results in bad json object.
if ( $request == null )
{
echo createErrorMsg("IPS-JSON request failed! Invalid header or postdata.");
exit;
}
// Check if we got a valid json object.
if (! isset($request->{'function'}) )
{
echo createErrorMsg("Request failed due to an invalid JSON object.");
exit;
}
// Check if the given method is callable.
if ( is_callable($request->{'function'}, false, $functionname) )
{
$result = call_user_func_array($functionname, $request->{'paras'});
if ( $result == "" )
{
echo createErrorMsg("Calling the requested function failed! Check syntax and parameters.");
exit;
}
echo json_encode($result);
} else
{
echo createErrorMsg("Invalid IPS function!");
exit;
}
/*
* Creates a JSON error object which can be returned to the caller.
*/
function createErrorMsg($text)
{
$arr = array(
"reqCtrlObject" => "ERROR",
"message" => $text
);
return json_encode($arr);
}
?>
Dazu habe ich auch einen Test PHP-Client zusammengebastelt… Dieser könnte wie folgt aussehen und bringt auch gleich die nötige Auth mit:
<?php
$request = IPSFunction("IPS_GetObject", array(0));
$ips_url = "https://mein.dyndnshost.de/json.php";
$ips_user = "meinlogin";
$ips_pass = "meinpass";
// Init php-curl.
$ch = curl_init();
curl_setopt($ch, CURLOPT_VERBOSE, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $ips_url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_USERPWD, "$ips_user:$ips_pass");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($request));
// Exec curl request.
$content = curl_exec($ch);
curl_close($ch);
if ( $content == false )
{
echo "JSON request failed!
";
} else
{
$result = json_decode($content);
if ( $result->{reqCtrlObject} == "ERROR" )
{
echo $result->{message} ."
";
} else
{
echo $content;
}
}
// Function which builds the request-object.
function IPSFunction($function, $paras)
{
$request = array(
"function" => $function,
"paras" => $paras
);
return $request;
}
?>
Da die JSON-Schnittstelle nicht sprachengebunden ist, könnte beispielsweise auch ein Curl-Aufruf von der Unix-Shell ein gewünschtes Ergebnis bringen.
curl -k -u meinlogin:meinpass-X POST -d '{"function":"IPS_GetObject","paras":[0]}' http://mein.dyndnshost.de/json.php
Wie gesagt, das ganze ist noch mit der heissen Nadel gestrickt und auch noch nicht ausgiebig getestet. So könnte ich mir jedenfalls eine/die neue/zusätzliche Schnittstelle vorstellen.
Ich werde an dem ganzen noch ein paar Optiomierungen vornehmen, mit anderen Sprachen testen und versuchen rauszufinden, wo es evtl. Schwachstellen bzw. Nachbesserungsbedarf gibt…
Any comments?
Viele Grüße
Sascha