Websocket

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
pascal.buehler
User
Beiträge: 8
Registriert: Dienstag 5. Oktober 2021, 08:32

Hallo zusammen ich habe da ein Problem mit dem zugriff auf einen Websocket. Mit dem MQTT Browser kann ich über ws direkt auf den Server zugreifen. jedoch mit python geht es nicht, ich glaube es liegt an der Autehtifikation. Wenn ich das ping pong mache, sehe ich per wireshark, dass ein pong an die adresse gemacht wird, jedoch kommt bei mir None. habe einige variationen getestet, aber nicht geht. Weiss jemand weiter oder ein guter Rat?


# Pakete importieren
import websocket
import ssl
import json
import time
import numpy as np
import csv
import matplotlib.pyplot as plt

# Allgemeine Einstellungen
path = ["C:\\Users\\buehlpas\\Desktop\\Messungen\\"]
name = ["Smart_Sensor_WS"]
ending = [".csv", ".svg"]
datum = time.localtime()
format('%4d')
# Definition Variablen
m = 1 # Anzahl Messdurchlauf
n = 10 # Anzahl Messpunkte
t0 = time.time()
t = []
u = []
v = []
w = []
z = []
header = ["Time t [s]", "MQTT Topic [num]", "MQTT Payload [num]"]
body = []
topics = [("sauter/ecos504/411001065754/status/analog-value/1/present-value", 0),
("sauter/ecos504/411001065754/status/analog-value/2/present-value", 0)]
active = True


# The callback for when the client is connected to the server.
def on_connect(ws):
print("Connection opened")


# The callback for when the client is disconnected to the server.
def on_close():
print("Connection closed")


# The callback for when the client has an error to the server.
def on_error(ws, error):
print(error)


# The callback for when a message is received from the server.
def on_receive(ws, msg):
global t
global active
print("Received message '" + str(msg.payload.decode("utf-8")) + "' on topic '"
+ msg.topic + "' with QoS " + str(msg.qos) + "' Count " + str(len(u)))
t.append(str(time.time() - t0))
# u.append(str(msg.topic).split("/")[5])
# v.append(str(msg.payload.decode("utf-8")))
# body.append([t[-1], u[-1], v[-1]])

if len(t) > n:
active = False


# The callback for when a message is published from the server.
def on_send(ws, payload):
print("Message Sent...")


def on_pong(ws, message):
print("Got a pong! No need to respond")


# Callback Function
websocket.enableTrace(True)
ws = websocket.WebSocket()
# ws.connect = on_connect
ws.close = on_close
ws.error = on_error
# ws.recv = on_receive
# ws.send = on_send
ws.pong = on_pong

# WS Definition
host = "192.168.10.70"
port = "9001"
username = 'admin'
password = 'sauter'

# connect to broker
ws.connect("ws://admin:sauter@192.168.10.70:9001", origin="192.168.10.11", subprotocols=["mqtt"])
print(ws.getheaders())
print(ws.getstatus())
print(ws.getsubprotocol())
print(ws.ping("This is an optional ping payload"))

# ws.send("ws://192.168.10.70:9001/sauter/ecos504/411001065754/status/analog-value/1/present-value", "10.00")
# wsapp = websocket.WebSocketApp("ws://192.168.10.70:9001/sauter/ecos504/411001065754/status/", on_message=on_message)

# Start the loop
# wsapp.run_forever(http_proxy_host=host, http_proxy_port=port, http_proxy_auth=(username, password))
# Smart Sensor datas

# Loop Bedingung
# while active:
# time.sleep(1)
# Bedingung Erfüllt Loop wird gestoppt
# wsapp.on_close
# Messung Ende, Schnittstelle freigeben
ws.close()
Benutzeravatar
grubenfox
User
Beiträge: 612
Registriert: Freitag 2. Dezember 2022, 15:49

wie lautet denn die Fehlermeldung?
ps: die komplette Fehlermeldung mit Stacktrace
pascal.buehler
User
Beiträge: 8
Registriert: Dienstag 5. Oktober 2021, 08:32

Backend TkAgg is interactive backend. Turning interactive mode on.
--- request header ---
DEBUG:websocket:--- request header ---
GET / HTTP/1.1
Upgrade: websocket
Host: 192.168.10.70:9001
Origin: 192.168.10.11
Sec-WebSocket-Key: o70eACx/Gh01pS4Ns1i+Cg==
Sec-WebSocket-Version: 13
Connection: Upgrade
Sec-WebSocket-Protocol: mqtt
DEBUG:websocket:GET / HTTP/1.1
Upgrade: websocket
Host: 192.168.10.70:9001
Origin: 192.168.10.11
Sec-WebSocket-Key: o70eACx/Gh01pS4Ns1i+Cg==
Sec-WebSocket-Version: 13
Connection: Upgrade
Sec-WebSocket-Protocol: mqtt
-----------------------
DEBUG:websocket:-----------------------
--- response header ---
DEBUG:websocket:--- response header ---
HTTP/1.1 101 Switching Protocols
DEBUG:websocket:HTTP/1.1 101 Switching Protocols
Upgrade: WebSocket
DEBUG:websocket:Upgrade: WebSocket
Connection: Upgrade
DEBUG:websocket:Connection: Upgrade
Sec-WebSocket-Accept: /2l6XoqBsTPkt6vc5H1TAHpm1vo=
DEBUG:websocket:Sec-WebSocket-Accept: /2l6XoqBsTPkt6vc5H1TAHpm1vo=
Sec-WebSocket-Protocol: mqtt
DEBUG:websocket:Sec-WebSocket-Protocol: mqtt
-----------------------
DEBUG:websocket:-----------------------
++Sent raw: b'\x89\xa0 \x87]\x03t\xef4p\x00\xee.#A\xe9}lP\xf34lN\xe61#P\xee3d\x00\xf7<zL\xe8<g'
DEBUG:websocket:++Sent raw: b'\x89\xa0 \x87]\x03t\xef4p\x00\xee.#A\xe9}lP\xf34lN\xe61#P\xee3d\x00\xf7<zL\xe8<g'
++Sent decoded: fin=1 opcode=9 data=b'This is an optional ping payload'
DEBUG:websocket:++Sent decoded: fin=1 opcode=9 data=b'This is an optional ping payload'
{'upgrade': 'WebSocket', 'connection': 'Upgrade', 'sec-websocket-accept': '/2l6XoqBsTPkt6vc5H1TAHpm1vo=', 'sec-websocket-protocol': 'mqtt'}
101
mqtt
None
Connection closed
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Code und Fehlermeldungen bitte in die dafuer vorgesehenen code-Tags packen, damit das verstaendlich ist - sonst gehen die in Python relevanten Einrueckungen verloren.
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Eingerückt wird immer mit 4 Leerzeichen pro Ebene, keine Tabs.
Variabelnamen sollten sprechend sein, einbuchstabige Namen sind das aber in der Regel nicht. Niemand (auch du nicht) kann mit t, u, v, w oder z etwas anfangen. Und statt mit Kommentaren zu beschreiben, was `m` bedeutet, wäre es besser gleich `number_of_measurement_runs` zu schreiben.
Globale Variablen benutzt man nicht; wenn man in Call-Backs Variablen braucht, dann schreibt man eine Klasse.
Der `format`-Aufruf steht da einfach nur rum, ohne irgendeinen Effekt zu haben, der kann weg.
Strings stückelt man nicht mit + zusammen sondern benutzt Formatstrings.
Wenn man Zeiträume messen will, benutzt man time.monotonic, nicht time.time.
Du scheinst zusammengehörige Daten in unterschiedlichen Liste u,v,t zu speichern, das macht man nicht, sondern, wie Du das ja schon mit body machst, in einer gemeinsamen Liste.
Das Hauptprogramm steht in einer Funktion `main`.

Code: Alles auswählen

import websocket
import time

NUMBER_OF_MEASUREMENT_POINTS = 10


class WebsocketService:
    def __init__(self):
        self.active = True
        self.t0 = time.monotonic()
        self.body = []
        self.websocket = websocket.WebSocket()
        # self.websocket.connect = self.on_connect
        self.websocket.close = self.on_close
        self.websocket.error = self.on_error
        # self.websocket.recv = self.on_receive
        # self.websocket.send = self.on_send
        self.websocket.pong = self.on_pong

    # The callback for when the client is connected to the server.
    def on_connect(self, ws):
        print("Connection opened")

    # The callback for when the client is disconnected to the server.
    def on_close(self):
        print("Connection closed")

    # The callback for when the client has an error to the server.
    def on_error(self, ws, error):
        print(error)

    # The callback for when a message is received from the server.
    def on_receive(self, ws, msg):
        topic = msg.topic.split("/")[5]
        payload = msg.payload.decode("utf-8")
        print(f"Received message '{payload}' on topic '{msg.topic}' with QoS {msg.qos}' Count {len(self.body)}")
        time_delta = time.monotonic() - self.t0
        self.body.append((time_delta, topic, payload))

        if len(self.body) > NUMBER_OF_MEASUREMENT_POINTS:
            self.active = False

    # The callback for when a message is published from the server.
    def on_send(self, ws, payload):
        print("Message Sent...")

    def on_pong(self, ws, message):
        print("Got a pong! No need to respond")

    def send(self, message):
        self.websocket.send(message)


def main():
    websocket.enableTrace(True)
    service = WebsocketService()

    # connect to broker
    service.websocket.connect("ws://admin:sauter@192.168.10.70:9001", origin="192.168.10.11", subprotocols=["mqtt"])
    print(service.websocket.getheaders())
    print(service.websocket.getstatus())
    print(service.websocket.getsubprotocol())
    print(service.websocket.ping("This is an optional ping payload"))

    # service.send("ws://192.168.10.70:9001/sauter/ecos504/411001065754/status/analog-value/1/present-value", "10.00")
    # wsapp = websocket.WebSocketApp("ws://192.168.10.70:9001/sauter/ecos504/411001065754/status/", on_message=on_message)

    # Start the loop
    # wsapp.run_forever(http_proxy_host=host, http_proxy_port=port, http_proxy_auth=(username, password))
    # Smart Sensor datas

    # Loop Bedingung
    # while active:
    # time.sleep(1)
    # Bedingung Erfüllt Loop wird gestoppt
    # wsapp.on_close
    # Messung Ende, Schnittstelle freigeben
    service.websocket.close()

if __name__ == "__main__":
    main()
Warum glaubst Du überhaupt, dass `ping` einen Rückgabewert hat?
pascal.buehler
User
Beiträge: 8
Registriert: Dienstag 5. Oktober 2021, 08:32

Ping nicht direkt, aber nachfolgend vom Ping auf das pong sollte der gleiche string zurückkommen.
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Du wartest den PONG aber gar nicht ab.
pascal.buehler
User
Beiträge: 8
Registriert: Dienstag 5. Oktober 2021, 08:32

mache ich nicht? war mir so nicht bewusst, wie macht man dann das?

müsste ich dann ein .recv(pong()) machen ?
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Code zu raten ist selten sinnvoll. Am besten fängt man mit dem Lesen der Dokumentation zum jeweiligen Paket an.
Bei websocket braucht man eine Ereignisschleife, die die ankommenden Nachrichten auch verarbeitet, und die entsprechenden Callbacks (hier on_pong) auch aufruft. Das fehlt bei Dir alles.
pascal.buehler
User
Beiträge: 8
Registriert: Dienstag 5. Oktober 2021, 08:32

Ja, da muss ich nochmals über read the docs.
Zeigt auch, dass die Beispiele dort nicht die besten sind und dass im Netz oftmals nur read the docs rezitiert wird. :-)
Antworten