Autor Thema: WebSocket via DevIO?  (Gelesen 12088 mal)

Offline KölnSolar

  • Developer
  • Hero Member
  • ****
  • Beiträge: 5142
Antw:WebSocket via DevIO?
« Antwort #45 am: 25 Mai 2020, 11:42:48 »
Danke Rudi. Ich probier es mal aus.

Trotzdem würde ich gerne verstehen(zu meiner Weiterbildung  ;D), warum das bei mir nicht klappte.
Zitat
auf Basis des in den Kommentaren verlinkten Artikels
Genau den suche ich immer wieder vergebens. Ich weiß, dass ich einen Link irgendwo gesehen hatte....Weißt Du noch wo bzw. wie der lautet ?

Zitat
Bei mir klappt das... Auch wenn die Lösung äußerst unschön ist. Eigentlich sollte das eine globale Variable o.ä. sein.
Wenn ich aber ein list device mache, gibt es bei mir keine helper-Variable. Bei Dir ?!?!?!?! Oder "versteckt" list den Eintrag u. führt mich in die Irre ?

RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt

Offline RichardCZ

  • Tester
  • Sr. Member
  • ****
  • Beiträge: 597
  • HoBo: zwischen Weltherrschaft und Intensivstation
    • Experimenteller FHEM Fork
Antw:WebSocket via DevIO?
« Antwort #46 am: 25 Mai 2020, 18:00:42 »
Perltidy krächzt.

419: return $doCb("websocket is only supported with callback") if(!$c ...
            -----^
found ( where operator expected (previous token underlined)

Do you mean '$doCb->(' ?

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 24155
Antw:WebSocket via DevIO?
« Antwort #47 am: 25 Mai 2020, 18:47:14 »
Danke fuer den Hinweis, habs gefixt.

Offline KernSani

  • Developer
  • Hero Member
  • ****
  • Beiträge: 3532
Antw:WebSocket via DevIO?
« Antwort #48 am: 31 Mai 2020, 23:48:38 »
Hallo Rudi,

danke für den Einbau. Leider scheitere ich in meinem Anwendungsfall schon beim Verbindungsaufbau. Der Websocket-Server ist in meinem Fall erreichbar unter einer URL der Form wss://host:port/irgendwas?undmehr=1&bla. Devio reduziert leider erstmal auf host:port (das passt ja auch für den tcpsocket) und hängt dann ein http/https für den nonBlocking-Connect vorne dran, dadurch ergibt sich https://host:port und die Websocketverbindung kommt natürlich nicht zu Stande.
Meine aktuelle Implementierung (auch vor Anpassung von DevIo) läuft vereinfacht gesagt wie folgt:
* DevIo baut tscpsocket auf (host:port)
* Basierend auf tcpsocket ($hash->{TCPDev}) wird Protocol::WebSocket::Client instantiiert (mit kompletter URL)
* Protocol::WebSocket::Client macht Handshake (upgrade etc...)
* ReadFn leitet $buf an Protocol::WebSocket::Client weiter, um Rückgabe zu bearbeiten.

Welchen Input benötigst du um das auf DevIO-Seite zu optimieren?

Danke,

Oli

RasPi: RFXTRX, HM, zigbee2mqtt, mySensors, JeeLink, miLight, squeezbox, Alexa, Siri, ...

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 24155
Antw:WebSocket via DevIO?
« Antwort #49 am: 01 Juni 2020, 00:58:35 »
Meines Wissens sollte das Beschriebene ohne "Optimierung" funktionieren.
wss:XX ist als ws:XX + $hash->{SSL}=1 zu spezifizieren, analog zu TCP, siehe mein Beispiel.

Offline KölnSolar

  • Developer
  • Hero Member
  • ****
  • Beiträge: 5142
Antw:WebSocket via DevIO?
« Antwort #50 am: 01 Juni 2020, 06:19:02 »
Hi Rudi,
auch ich habe mich mühevoll versucht. Die Definition ist ja eigentlich einfach. Ich dachte, dass es an TLS liegt, aber scheinbar ist es etwas anderes beim handshake, das die Verbindung nicht zustande kommen lässt. Mit wscat u. der Test-Website, die Jörg genannt hatte, funktioniert alles bestens.

Ich hab nun die Möglichkeit das Ganze ohne TLS auszuprobieren. Ich guck mir das im Laufe des Tages mit tcpdump/Wireshark mal an.

Wunsch: Den opcode des frames zurückliefern. Insbesondere beim Test fänd ich es hilfreich, wenn die Info ankommt, dass der Server die Verbindung "geclosed" hat. Ich guck aber selber mal, ob man das einfach in DevIo unterbringen kann.

Grüße Markus
RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt

Offline KölnSolar

  • Developer
  • Hero Member
  • ****
  • Beiträge: 5142
Antw:WebSocket via DevIO?
« Antwort #51 am: 01 Juni 2020, 09:55:05 »
Lt. Wireshark antwortet der Server auf den upgrade websocket request
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: t4n9guUpD/ZNPtfze+r3aUVqTo0=
Date: Mon, 01 Jun 2020 07:32:51 GMT
Server: Python/3.5 websockets/7.0

dann noch ein TCP-Ack des FHEM-Servers an den websocket-Server, aber dann wartet FHEM den timeout(3s) ab.... :'(

Und so sieht das im FHEM-Log aus
2020.06.01 09:32:51 3: [EE2] sol_local EE2_Ready(connection seems to be lost) retrying wsconnect for DeviceName: ws:xxxip.de:9124
2020.06.01 09:32:51 5: HttpUtils url=http://xxxip.de:9124/
2020.06.01 09:32:51 4: IP: xxxip.de -> Ipdeshosts
2020.06.01 09:32:51 5: HttpUtils request header:
GET / HTTP/1.1
Host: xxxip.de:9124
User-Agent: fhem
Accept-Encoding: gzip,deflate
Sec-WebSocket-Key: sXh1fxWrbbVHEyfLPyO77Q==
Connection: Upgrade
Sec-WebSocket-Version: 13
Upgrade: websocket

2020.06.01 09:32:54 4: [EE2] sol_local - error while connecting to Websocket: read from http://xxxip.de:9124 timed out from DevIO
2020.06.01 09:32:54 4: [EE2] sol_local - callback called

Auf was wartet httputils bzw. DevIo da noch ?!?!?!?

Wenn Du mehr brauchst, melde Dich gerne
Grüße Markus

Correction: additional new line added
« Letzte Änderung: 01 Juni 2020, 20:32:10 von KölnSolar »
RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 24155
Antw:WebSocket via DevIO?
« Antwort #52 am: 01 Juni 2020, 11:07:50 »
Zitat
Auf was wartet httputils bzw. DevIo da noch ?!?!?!?
Falls Du die Daten vollstaendig kopiert hast: auf einem zweiten NL nach dem Header.
Ich fuerchte mit dieser Methode kommen wir nur muehsam weiter: gibt es eine Moeglichkeit, dass ich mich direkt mit deinem Server verbinde?

Ich habe DevIo.pm erweitert: mit verbose 5 wird jedes websocket Frame geloggt, und wss: ist equivalent zu ws: + $hash->{SSL}=1;

Offline KölnSolar

  • Developer
  • Hero Member
  • ****
  • Beiträge: 5142
Antw:WebSocket via DevIO?
« Antwort #53 am: 01 Juni 2020, 11:36:08 »
Mit TLS kannst Du es auf sol.eet.energy:9124 testen.

Was ist ein NL ?  :-[

Danke fürs logging. Ich hol mir mal die aktuelle Version...

Allerdings genügt das Logging vermutlich nicht  :'( Ich konnte verfolgen, dass der Server alle 20s einen ping sendet, womit dann mit einem pong geantwortet wird(ansonsten schließt der Server die websocket-Verbindung). Ein websocket-frame ohne Daten kommt aber nicht im Modul über die ReadFn an, oder ? Oder ist das etwas, was in DevIo rein müsste ?
Ich glaube im konkreten Fall kommt kein Ping mehr, wenn man die ersten Daten(Logindaten)) geschickt hat...

Für ein anderes Modul überlege ich mir, ob ich auch auf DevIo umbaue. Allerdings ist das ein device, das nicht regelmäßig verfügbar ist. Du schreibst ja hier u. da, dass DevIo dann eher keinen Sinn macht. Was hältst Du von einer Lösung, wo die Verfügbarkeit des devices mit einem anderen Mechanismus überwacht wird und nur für die Dauer der Verfügbarkeit eine websocket-Verbindung aufgebaut bleibt, also Aufbau, wenn verfügbar und ein close(und damit auch kein ReadyFn/ReadFn ), wenn nicht mehr verfügbar.

Grüße Markus
« Letzte Änderung: 01 Juni 2020, 11:39:39 von KölnSolar »
RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 24155
Antw:WebSocket via DevIO?
« Antwort #54 am: 01 Juni 2020, 12:30:18 »
Zitat
Mit TLS kannst Du es auf sol.eet.energy:9124 testen.
Habs gemacht.
Eine websocket Verbindung wird zwar hergestellt, aber von der anderen Seite sofort geschlossen (mit OP:8 == Close), vermutlich weil das von mir gesendete "list" ohne Weiteres dem Server nicht passt.

NL steht fuer NewLine: ein HTTP Header wird mit zwei Newlines abgeschlossen, und in deinem Beitrag sieht man nur eins.
Ein Websocket Frame wird mit DevIO nie beim Modul ankommen, da das Prinzip von DevIo ist, vom Transportschicht-Eigenheiten zu abstrahieren.
Abgesehen davon wuesste ich nicht, warum Ping/etc das Modul interessieren sollte.

Zitat
Du schreibst ja hier u. da, dass DevIo dann eher keinen Sinn macht.
Das ist vermutlich falsch interpretiert, kannst Du mir diesen Zitat zeigen?
Websocket ist (im Gegensatz zu HTTP) fuer eine laenger geoeffnete Verbindung ausgelegt.
Man kann es (wie alles) missbrauchen, und ob man das mit DevIo oder ohne macht, ist mir egal.

Zitat
Was hältst Du von einer Lösung, wo die Verfügbarkeit des devices mit einem anderen Mechanismus überwacht wird und nur für die Dauer der Verfügbarkeit eine websocket-Verbindung aufgebaut bleibt,
Wenig, wenn beide Verfahren das gleiche Medium (Netzwerk) nutzen.
Wenn die andere Seite nicht da ist, dann kriegt man das auch per websocket mit: ob jetzt ping oder der TCP Connect-Versuch keine Antwort kriegt, ist  egal. Es kommt dazu, dass man fuer ping entweder spezielle Rechte (root), oder unangemessen viel Ressourcen (fork+exec) braucht.
Heisst nicht, dass ich die, die sowas programmieren, aktiv verfolge, ich aussere nur meine Meinung, wenn ich danach gefragt werde :)
Zustimmung Zustimmung x 1 Liste anzeigen

Offline KölnSolar

  • Developer
  • Hero Member
  • ****
  • Beiträge: 5142
Antw:WebSocket via DevIO?
« Antwort #55 am: 01 Juni 2020, 12:53:31 »
Hi Rudi,
Zitat
Eine websocket Verbindung wird zwar hergestellt, aber von der anderen Seite sofort geschlossen (mit OP:8 == Close), vermutlich weil das von mir gesendete "list" ohne Weiteres dem Server nicht passt.
Ja, das macht er, wenn ihm was nicht passt.  ;) Wie hast Du das denn jetzt mit dem "fehlenden" 2. NL gelöst ? Geänderte  DevIo sehe ich nicht.  :-[

Zitat
Abgesehen davon wuesste ich nicht, warum Ping/etc das Modul interessieren sollte.
Das sehe ich dann, wenn es mal mit dem Modul klappt.... ;)
Zitat
Das ist vermutlich falsch interpretiert, kannst Du mir diesen Zitat zeigen?
Finde ich bestimmt nicht mehr, aber Du hast ja jetzt ausführlich aufgeklärt.

Danke&Grüße Markus
« Letzte Änderung: 01 Juni 2020, 20:33:02 von KölnSolar »
RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt

Offline KölnSolar

  • Developer
  • Hero Member
  • ****
  • Beiträge: 5142
Antw:WebSocket via DevIO?
« Antwort #56 am: 01 Juni 2020, 13:58:54 »
Hm,
mein lokales device gibt auch nur ein NL zurück.  Das war wohl Quatsch. Du meintest ja die response. :( Trotzdem selbes Problem mit meinem lokalen device.

2020.06.01 13:50:57 5: HttpUtils url=https://localIP:8002/
2020.06.01 13:50:57 4: IP: localIP -> localIP
2020.06.01 13:50:57 5: HttpUtils request header:
GET / HTTP/1.1
Host: localIP:8002
User-Agent: fhem
Accept-Encoding: gzip,deflate
Sec-WebSocket-Key: 9nXYHmyxKMPCKREAHTn2Ng==
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Version: 13

2020.06.01 13:51:00 5: [SamsungAV] Fernseher - callback after connecting to Websocket by DevIO
2020.06.01 13:51:00 2: [SamsungAV] Fernseher - error while connecting to Websocket: read from https://localIP:8002 timed out from DevIO

Edit: Das mit dem NL ist es wohl nicht. Hab nochmal in Wireshark geguckt. Die response endet mit \r\n\r\n. Ich passdie obigen Posts mal an.
« Letzte Änderung: 01 Juni 2020, 20:29:50 von KölnSolar »
RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 24155
Antw:WebSocket via DevIO?
« Antwort #57 am: 01 Juni 2020, 20:20:33 »
Zitat
mein lokales device gibt auch nur ein NL zurück.
Du verwirrst mich.
Im Code-Stueck sind zwei zu sehen: einmal nach "Sec-WebSocket-Version: 13" und danach die leere Zeile.
Der Zugriff auf "sol.eet.energy:9124" klappte ohne Aenderung, der schickt schon 2 NLs.

Offline KölnSolar

  • Developer
  • Hero Member
  • ****
  • Beiträge: 5142
Antw:WebSocket via DevIO?
« Antwort #58 am: 01 Juni 2020, 20:44:54 »
Ich mich auch. Hab jetzt erst gemerkt, dass Du ja die response meintest. Ja, da kommt die 2. NL. Hatte ich nur nicht mitkopiert. :o

Aber dann sind wir so weit wie heute Morgen: Was führt zu dem timeout ? Und viel schlimmer: wieso klappt das bei Dir ? ??? Da kann man doch eigentlich nichts falsch machen.  :-[

    $hash->{DeviceName} = "ws:".$hash->{Host} . ":" . $hash->{Port}; 
#    $hash->{SSL}         = 1;  # TLS only used for remote access; set by attribute   
#    $hash->{WEBSOCKET}   = 1;  set by Dev
    DevIo_OpenDev( $hash, 0, "wsHandshake", "wsCb" );
sub wsCb ($){
    my ($hash, $error)  = @_;

    my $name  = $hash->{NAME};

    if (defined($error)) {Log3 $name, 4, "[EE2] $name - error while connecting to Websocket: $error from DevIO" };
    Log3 $name, 4, "[EE2] $name - callback called";
    return $error;
}
« Letzte Änderung: 01 Juni 2020, 20:58:57 von KölnSolar »
RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt

Offline KölnSolar

  • Developer
  • Hero Member
  • ****
  • Beiträge: 5142
Antw:WebSocket via DevIO?
« Antwort #59 am: 02 Juni 2020, 09:03:31 »
Hi Rudi,
nachdem es also nicht am NL liegt, wird für mich die Sache immer ominöser. Was mich in meinem Log so blind gemacht hatte ist, dass es überflutet wurde. Das liegt daran, dass permanent die ReadyFN aufgerufen und ein Neuaufbau versucht wird. Es ist doch richtig, dass die ReadyFn eigentlich gar nicht aufgerufen werden dürfte oder zumindest der STATE auf connected stehen müsste, oder ?

Außerdem hadere ich mit dem reopen-Flag. Ich hab jetzt noch einmal ein wenig umgebaut und bekomme folgendes Logging
2020.06.01 23:17:38 3: [EE2] sol_local defined with host: localDomain port: 9124
...Versatz von 20s ist korrekt, weil der Aufbau über einen internaltimmer 20s nach dem define gestartet wird
2020.06.01 23:17:58 4: [EE2] sol_local  Attempting to open websocket by DevIo
2020.06.01 23:17:58 3: Opening sol_local device ws:localDomain:9124
2020.06.01 23:17:58 5: HttpUtils url=http://localDomain:9124/
2020.06.01 23:17:58 4: IP: localDomain -> localIP
2020.06.01 23:17:58 5: HttpUtils request header:
GET / HTTP/1.1
Host: localDomain:9124
User-Agent: fhem
Accept-Encoding: gzip,deflate
Upgrade: websocket
Sec-WebSocket-Version: 13
Connection: Upgrade
Sec-WebSocket-Key: 7i8DGRzM9v3nc2QrBABKIw==

2020.06.01 23:18:01 1: sol_local: Can't connect to localDomain:9124: No such file or directory
2020.06.01 23:18:01 1: sol_local: Can't connect to localDomain:9124: read from http://localDomain:9124 timed out
2020.06.01 23:18:01 4: [EE2] sol_local - error while connecting to Websocket: read from http://localDomain:9124 timed out from DevIO
2020.06.01 23:18:01 3: [EE2] sol_local EE2_Ready(connection seems to be lost) retrying wsconnect for DeviceName: ws:localDomain:9124
2020.06.01 23:18:01 3: Opening sol_local device ws:localDomain:9124
2020.06.01 23:18:01 4: [EE2] sol_local - connecting to Websocket successful
2020.06.01 23:18:01 3: [EE2] sol_local EE2_Ready(connection seems to be lost) retrying wsconnect for DeviceName: ws:localDomain:9124
2020.06.01 23:18:01 4: [EE2] sol_local - connecting to Websocket successful
2020.06.01 23:18:02 3: [EE2] sol_local EE2_Ready(connection seems to be lost) retrying wsconnect for DeviceName: ws:localDomain:9124
2020.06.01 23:18:02 4: [EE2] sol_local - connecting to Websocket successful
.
.
.
bei diesem coding.
.
Initial-websocket-connect
    $hash->{helper}{wsconnect} = 0;
    Log3 $name, 4, "[EE2] $name  Attempting to open websocket by DevIo";
    $hash->{DeviceName} = "ws:".$hash->{Host} . ":" . $hash->{Port}; 
    DevIo_OpenDev( $hash, 0, "wsHandshake", "wsCb" );
.
.
ReadyFN
   Log3 $hash->{NAME}, 3, "[EE2] $hash->{NAME} EE2_Ready(connection seems to be lost) retrying wsconnect for DeviceName: $hash->{DeviceName}";
  return DevIo_OpenDev( $hash, $hash->{helper}{wsconnect}, "wsHandshake", "wsCb" )
                if($hash->{STATE} eq "disconnected");     

wsCb
    if (defined($error)) {Log3 $name, 4, "[EE2] $name - error while connecting to Websocket: $error from DevIO" }
    else {
       Log3 $name, 4, "[EE2] $name - connecting to Websocket successful";
       $hash->{helper}{wsconnect} = 1;
    }
Auf ein write habe ich komplett verzichtet, da ggfs. der Server mit einem disconnect reagiert.

Aber wieso gibt es erst diese "Can't connect" Meldung mit 3s timeout, dann der identische Aufruf von DevIo(reopen=1), der nun scheinbar erfolgreich ist, aber nicht zu einem "connected" führt bzw. die ReadyFn aufgerufen wird, wo dann erneut ein erfolgreicher ws-connect(reopen=1) erfolgt, der aber wieder in die ReadyFN läuft. Und das dann permanent.

Soll ich das nochmal genau mit Wireshark analysieren ?

Grüße Markus
RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt

 

decade-submarginal