Websocket Verbindung

Hallo,

wenn ich diesen javascript Code auf dem Websockedserver ausführe:

test = function() {
 var obj = {Data: "Testnachricht"};
ws.push("special.event", obj);
}

und ich diese Html Datei in einem Browser starte

<script type="text/javascript">
var websocket = new WebSocket('ws://localhost:1111');
    websocket.onopen = function(ev) {
        console.log("connected");        
// this makes client to receive only relevant events:
//        websocket.send("special.event");
    };    
websocket.onclose = function(ev) { 
       console.log("disconnected");
    };
    websocket.onmessage = function(ev) {
        if (!ev.data) { 
           console.log("ping");
        } else { 
           console.log(ev.data); 
       }
    }; 
   websocket.onerror = function(ev) {
        console.log("error: " + ev.data); 
   };
</script>

sehe ich in der javascriptconsole des Browsers, das es funktioniert.

Wie gehe ich vor damit ich die Daten in IPS empfangen kann.

Habe ein Clientsoket erstellt, der auch eine Verbindung herstellt.
Dann eine Registervariable die ein Script aufruft:

<?if($_IPS["SENDER"] == "RegisterVariable") {
    $rawdata=$_IPS["VALUE"];
    IPS_LogMessage("Websocket Test",$rawdata); 
   IPS_LogMessage("Websocket Test","Registervariable hat script ausgeführt");
}
?>

Aber das Script wird nicht aufgerufen. Warum?

Gruß
Steffen

ClientSocket macht nicht wirklich Sinn. Evtl. würde es mit einem ServerSocket gehen.

paresy

Danke, aber er ist schon etwas weiter gekommen damit. Passt soweit. Jetzt hab ich „nur noch“ die Aufgabe das mit ins Modul zu integrieren mit ClientSocket und RegVar…mal sehen, ob ich das hin bekomme :rolleyes: :slight_smile:

Grüße,
Chris

Regvar haben in einem Modul nix zu suchen :slight_smile:
Michael

Also muss/sollte das Modul direkt mit dem ClientSocket kommunizieren? Hab mir das noch nicht angeschaut. Denke ich kann dann dein Squeezebox Modul als Vorlage nehmen?!

Grüße,
Chris

Ja. Es sollte direkt kommunizieren. Und bei WebSocket macht eher ServerSocket Sinn. Da du aber nicht weißt von wem die Daten sind, kann immer nur ein Client kommunizieren :wink:

paresy

Ich habe es so verstanden dass der Webserver socket im Browser läuft.
Dann passt ja ein clientsocket.
Ich würde lieber Paresy Testmodul nehmen anstatt das von der Squeezebox.
Michael

Die Quelle ist ein „Webserver“ (ist immer nur ein bestimmter). Dieser schickt von alleine „Daten“ an den ClientSocket im IPS und dort muss das Modul die Daten dann verarbeiten und Variablen setzen und so einen Kram halt machen. Funktioniert soweit…muss das halt „nur noch“ in das Modul integrieren :rolleyes: :smiley:

Grüße,
Chris

Ich suche auch so was händeringend. Das würde vieles erleichtern und wäre dann eine sinnvolle Alternative zum Umweg Node.js um dann von dort Variablen in IPS zu setzten. Falls Du da da irgendwas zum Laufen bekommst lass es uns wissen :). Die Bedarf wäre sicher groß vor allem beim aktualisieren von z.B. Sonos, AVR Recievern mit Webinterface usw.

Wenn ich das einbaue, was ich machen werde - sobald ich dazu komme, wird es dir aber nichts bringen. Weil dein Gerät bzw. die andere Software ja den WebSocket „bieten/beherrschen“ muss und dieser schickt dann an den ClientSocket im IPS. Muss man also für jede Hardware/Software eine individuelle Lösung basteln.

Grüße,
Chris

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é