通过 websockets 连接到 Mqtt

物联网 MQTT 树莓派 网络套接字 Python
2021-06-23 14:47:43

我正在尝试使用以下脚本连接代理

#!/user/bin/env python

import paho.mqtt.client as mqtt
import random
import requests
import warnings
import LoggingManager

logger = LoggingManager.log_setup()
logger.info("Start Working")

my_client_id = f'python-mqtt-{random.randint(0, 1000)}'
# method = "websockets"
my_endpoint = "wss://psmart-test-api.aegean.gr/ws/"
# port = 443
# keepalive = 60
key = "ea75d54ea85b54ba5cde22ffb31090f9b2cbaeba8ad6eef1be575bfae89f56d3"
url_login = "https://psmart-test-auth.aegean.gr/auth/refresh_session"

warnings.filterwarnings('ignore', message='Unverified HTTPS request')


def myNewlogin(key, url_login):
    loginobj = '''{ "token": "%s"  }''' % (key)
    loginHeaders = {'Content-Type': 'application/json'}
    login_response = requests.request("POST", url_login, data=loginobj, headers=loginHeaders, verify=False)

    table = {}
    table["status_code"] = login_response.status_code

    if (login_response.status_code == 200):
        result = login_response.json()
        mytoken = result["token"]
        table["token"] = mytoken
    else:
        table["token"] = login_response.text
    return (table)


is_connected = False

# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    print("Connected with result code " + str(rc))
    global is_connected
    is_connected = True
    # Subscribing in on_connect() means that if we lose the connection and
    # reconnect then subscriptions will be renewed.
    # client.subscribe("$SYS/#")
    # client.subscribe("org/TERIADE/K4XKF6UT/Temperature")


# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    print(msg.topic + " " + str(msg.payload))


def on_disconnect(client, userdata, rc):
    print("Disconnected")


# authenticate to take username
# user = str(myNewlogin(key, url_login))
# print(user)

login = myNewlogin(key, url_login)

if (login["status_code"] == 200):  # if we can login
    # print("mylogin 200")
    logger.info("mylogin 200")
else:
    # print(login)
    logger.info("mylogin" + str(login["status_code"]))


# Create a client instance
client = mqtt.Client(my_client_id, transport='websockets')

# Register callbacks
client.on_connect = on_connect
client.on_message = on_message

# client.tls_set(ca_certs="https://psmart-api.aegean.gr/roots.pem")

# client.tls_set()

# Set userid and password
client.username_pw_set(login["token"])

# Connect
client.connect(my_endpoint, 443, 60)

client.loop_start()

publish_interval = 5
value = 0
while 1 == 1:
    if is_connected == True:
        print('hello')
    else:
        print("still waiting for connection")
    time.sleep(publish_interval)


# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
# Other loop*() functions are available that give a threaded interface and a
# manual interface.
# client.loop_forever()

# while 1:
    # Publish a message every second
    # time.sleep(1)

我收到以下错误

Traceback (most recent call last):
  File "mqtt_client_psmart.py", line 91, in <module>
    client.connect(my_endpoint, 443, 60)
  File "/usr/local/lib/python3.7/dist-packages/paho/mqtt/client.py", line 941, in connect
    return self.reconnect()
  File "/usr/local/lib/python3.7/dist-packages/paho/mqtt/client.py", line 1075, in reconnect
    sock = self._create_socket_connection()
  File "/usr/local/lib/python3.7/dist-packages/paho/mqtt/client.py", line 3546, in _create_socket_connection
    return socket.create_connection(addr, source_address=source, timeout=self._keepalive)
  File "/usr/lib/python3.7/socket.py", line 707, in create_connection
    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
  File "/usr/lib/python3.7/socket.py", line 748, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -2] Name or service not known

我找不到解决办法。有任何想法吗?提前致谢

在@hardillb 的帮助下,我进行了以下更改:

# Configure network encryption and authentication options. Enables SSL/TLS support.
client.tls_set()

# Set userid and password
client.username_pw_set(login["token"])

# Set websocket connection options.
client.ws_set_options(path="/ws", headers=None)

# Connect
client.connect('psmart-test-api.aegean.gr', 443, 60)

代码现在正在运行......我仍在等待连接但另一个问题......

1个回答

client.connect()函数采用主机名,而不是 URL 作为它的第一个参数。

失败是因为客户端试图解析wss://psmart-test-api.aegean.gr/ws/为主机名。

您应该只是psmart-test-api.aegean.gr作为函数的第一个参数传递

要更改连接 URL 的路径部分,您将需要使用在此处ws_set_options(self, path="/mqtt", headers=None)查看文档