eclipse / paho.mqtt.python

paho.mqtt.python
Other
2.19k stars 723 forks source link

How to connect with websockets on ports 443. #745

Closed bnuzhouwei closed 9 months ago

bnuzhouwei commented 1 year ago

I has a broker that host mqtt server with websockets on https

connect:

broker = 'mybroker.com'
port = 443
client = mqtt_client.Client(client_id, transport="websockets")    
client.username_pw_set(username, password)
client.on_connect = on_connect
client.connect(broker, port)

got error:

paho.mqtt.client.WebsocketConnectionError: WebSocket handshake error, connection not upgraded
petersilva commented 11 months ago

You need to set up an SSL context, and supply that to connect()

code fragments from my application:

    def __sslClientSetup(self) -> int:
        """
          Initializse self.client SSL context, must be called after self.client is instantiated.
          return port number for connection.

        """
        if self.o['broker'].url.scheme[-1] == 's':
            port = 8883
            logger.info('tlsRigour: %s' % self.o['tlsRigour'])
            self.o['tlsRigour'] = self.o['tlsRigour'].lower()
            if self.o['tlsRigour'] == 'lax':
                self.tlsctx = ssl.create_default_context()
                self.tlsctx.check_hostname = False
                self.tlsctx.verify_mode = ssl.CERT_NONE

            elif self.o['tlsRigour'] == 'strict':
                self.tlsctx = ssl.SSLContext(ssl.PROTOCOL_TLS)
                self.tlsctx.options |= ssl.OP_NO_TLSv1
                self.tlsctx.options |= ssl.OP_NO_TLSv1_1
                self.tlsctx.check_hostname = True
                self.tlsctx.verify_mode = ssl.CERT_REQUIRED
                self.tlsctx.load_default_certs()
                # TODO Find a way to reintroduce certificate revocation (CRL) in the future
                #  self.tlsctx.verify_flags = ssl.VERIFY_CRL_CHECK_CHAIN
                #  https://github.com/MetPX/sarracenia/issues/330
            elif self.o['tlsRigour'] == 'normal':
                self.tlsctx = ssl.create_default_context()
            else:
                self.logger.warning(
                    "option tlsRigour must be one of:  lax, normal, strict")
            self.client.tls_set_context(self.tlsctx)
        else:
            port = 1883

        if self.o['broker'].url.port:
            port = self.o['broker'].url.port
        return port

then in connect:

  self.client.connect( self.o['broker'].url.hostname, port=self.__sslClientSetup(), \
                           clean_start=False, properties=props )
MattBrittan commented 9 months ago

Closing this as it looks like the question has been answered.