Skip to content

Websocket connection fails without connection.on(error) getting called. #445

Open
@Epick362

Description

Describe the bug

I am using a backend "secrets" endpoint (using STS assumeRole) that generates credentials for MQTT connection for the current user. This works well for our use case except for the fact that these credentials expire and even though there is code on the client to attempt a reconnect (request new set of credentials), the connection.on(error) event handler does not get called. I see this in the console:

GET
wss://x-ats.iot.eu-west-1.amazonaws.com/mqtt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=Z&X-Amz-Date=20231122T152819Z&X-Amz-SignedHeaders=host&X-Amz-Signature=Y&X-Amz-Security-Token=X

Firefox can’t establish a connection to the server at wss://x-ats.iot.eu-west-1.amazonaws.com/mqtt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=Z&X-Amz-Date=20231122T152819Z&X-Amz-SignedHeaders=host&X-Amz-Signature=Y&X-Amz-Security-Token=X.

Is there a way to react to this error? I looked into websocket options in the client config but couldn't find anything relevant.
This is how I build the connection on client after receiving credentials:

    const client_bootstrap = new io.ClientBootstrap()
    const config_builder = iot.AwsIotMqttConnectionConfigBuilder.new_with_websockets()

    const clientId = `X-${user?.id}-${uuidv4()}`
    config_builder.with_client_id(clientId)
    config_builder.with_endpoint(credentialsResponse.credentials.iotEndpoint)
    config_builder.with_credentials(
      credentialsResponse.credentials.region,
      credentialsResponse.credentials.accessKey,
      credentialsResponse.credentials.secretKey,
      credentialsResponse.credentials.sessionToken,
    )

    const config = config_builder.build()
    const client = new mqtt.MqttClient(client_bootstrap)
    const connection = client.new_connection(config)

and these are the relevant event handlers I've tried

        connection.on('disconnect', () => {
          this.connected = false
          log.warn('MQTT connection disconnect')

          this.attemptReconnect()
        })

        connection.on('interrupt', () => {
          if (!this.connected) {
            return
          }

          this.connected = false
          log.warn('MQTT connection interrupt')

          this.attemptReconnect()
        })

        connection.on('error', (e) => {
          this.connected = false
          console.error('MQTT connection error')

          reject(e)

          // Queue exponential backoff reconnect
          this.attemptReconnect()
        })

Expected Behavior

The connection.on(error) handler gets invoked and I can manage new credentials request.

Current Behavior

My client SDK is stuck without websocket connection and thinks it is connected successfully.

Reproduction Steps

Initiate a websocket MQTT connection using temporary credentials and wait for them to timeout.

Possible Solution

No response

Additional Information/Context

No response

SDK version used

1.17.0

Environment details (OS name and version, etc.)

any browser

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    bugThis issue is a bug.p2This is a standard priority issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions