Hallo Bayaro,
ich möchte eine bidirektionale Verbindung zwischen IPS und einer App auf dem Handy per WebSocket herstellen.
Ich bin soweit, dass ich per JS die Anfrage an einen ServerSocket mit Port 10000 auf IPS stelle. An den habe ich einen Splitter mit Registervariable gehängt. Kommt der Input feuert er auch (Die zyklisch gesendeten XML´s werden richtig verarbeitet).
Das Cutter-Script sieht so aus (Daten werden als XML empfangen, der Handshake soll ein anderes Script triggern):
<?
// wenn das Skript von einer RegisterVariable-Instanz aus aufgerufen worden ist
if ($_IPS['SENDER'] == "RegisterVariable")
{
$data = $_IPS['VALUE'];
// wenn das "xml" in $data gefunden worden ist
if (strpos($data, '<?xml version="1.0" encoding="utf-8"?>'))
{
// $data in durch ; separierte Datensätze zerlegen
$data = explode('<?xml version="1.0" encoding="utf-8"?>', $data);
$data = '<?xml version="1.0" encoding="utf-8"?>'.$data[1];
SetValue(25436 /*[Robomow\Statusmeldungen]*/, $data);
}
//wenn der WebSocket verbinden will
if (strpos($data, 'Upgrade: websocket'))
{
$ObjektID_Kategorie_Robomow = IPS_GetObjectIDByName("Robomow", 0);
include_once (IPS_GetScriptIDByName("Robomow Communication", $ObjektID_Kategorie_Robomow).".ips.php");
$WFC_ID = 47627 /*[WebFront]*/;
$WFC_Header = "Websocket";
//WFC_SendPopup($WFC_ID, $WFC_Header, $WFC_Content);
}
}
//zum Löschen der Registervariable
RegVar_SetBuffer(27564 /*[Cutter Robomow [10000]\Register Variable]*/, "");
?>
Das eigentliche Script für den Handshake sieht derzeit so aus:
<?
$host = '192.168.178.4'; // IP des Websocket-Server
$port = '10000';
$secKey_temp = explode("Sec-WebSocket-Key: ", $data);
$secKey_temp = explode("<CR><LF>Sec-WebSocket-Extensions:", $secKey_temp[1]);
$secKey = $secKey_temp[0];
//Globally Unique Identifier 258EAFA5-E914-47DA-95CA-C5AB0DC85B11
$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
$handshake = "HTTP/1.1 101 Web Socket Protocol Handshake
" .
"Upgrade: websocket
" .
"Connection: Upgrade
" .
"WebSocket-Origin: $host
" .
"WebSocket-Location: ws://$host:$port
".
"Sec-WebSocket-Accept: $secAccept
";
echo("$handshake");
SSCK_SendText(10974 /*[Robomow Server Socket [10000]]*/, $handshake);
?>
Es scheitert jedoch am Handshake mit „Error during WebSocket handshake: Incorrect ‚Sec-WebSocket-Accept‘ header value“. Zum Testen setze ich die Webssockets-Demo ein (in App.js noch das Ziel ändern; z.B. ws://xxx.xxx.xxx.xxx:10000).
websockets-demo.zip (2.25 KB)
Die Kommunikation im Debug-Fenster sieht jedoch richtig aus:
GET / HTTP/1.1<CR><LF>Host: 192.168.178.4:10000<CR><LF>Connection: Upgrade<CR><LF>Pragma: no-cache<CR><LF>Cache-Control: no-cache<CR><LF>Upgrade: websocket<CR><LF>Origin: file://<CR><LF>Sec-WebSocket-Version: 13<CR><LF>User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36<CR><LF>Accept-Encoding: gzip, deflate, sdch<CR><LF>Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4<CR><LF>Sec-WebSocket-Key: uiQx0EQmXM5ZEnhJkO9uYg==<CR><LF>Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits<CR><LF><CR><LF>
HTTP/1.1 101 Web Socket Protocol Handshake<CR><LF>Upgrade: websocket<CR><LF>Connection: Upgrade<CR><LF>WebSocket-Origin: 192.168.178.4<CR><LF>WebSocket-Location: ws://192.168.178.4:10000<CR><LF>Sec-WebSocket-Accept: lzpBFmWNwidDqVfONUbc2/TbQiQ=<CR><LF><CR><LF>
Bist Du eventuell mit einer Websocket - Lösung schon weiter bzw. kannst sie uns zugänglich machen, oder mir hier einen Tipp geben ?
Gruß André