Hello everyone! I recently had the opportunity to work with AWS IoT to fetch real-time data. During the migration from Webpack 4 to Webpack 5, we encountered some issues with the aws-iot-device-sdk. While building our project, we encountered errors related to tls, buffer, and stream. To resolve these issues, we made the following modifications to our webpack configuration:
We added fallback options in the resolve section of webpack.config.js. These fallbacks ensure that if the required packages (crypto-browserify, path-browserify, stream-browserify, buffer) are not found, alternative options are used. We also set
fs
andtls
to false to prevent conflicts.Here's an example of the code snippet:
resolve: { fallback: { crypto: require.resolve('crypto-browserify'), path: require.resolve('path-browserify'), stream: require.resolve('stream-browserify'), buffer: require.resolve('buffer'), fs: false, tls: false } }
We added a loader for .mjs files. This loader helps resolve issues related to file resolution.
Here's an example of the code snippet:
{ test: /\.m?js/, resolve: { fullySpecified: false } }
By implementing these changes, we were able to resolve the issues with aws-iot-device-sdk. However, we later discovered that this solution significantly increased our build time, which became a major concern.
Upon further investigation, we found that AWS provides another library for IoT called aws-iot-device-sdk-v2. We decided to replace the existing package with this new one. However, we encountered major breaking changes in how the connection with aws-iot is initiated. Although we couldn't find documentation on GitHub, we found some sample code there to guide us.
To establish a connection, we first needed to create a configuration that includes the IoT credentials and endpoint.
Here's an example of the code snippet:
import { mqtt, iot } from "aws-iot-device-sdk-v2";
let config = iot.AwsIotMqttConnectionConfigBuilder.new_default_builder()
.with_clean_session(true)
.with_client_id(`custom_authorizer_connect_sample(${new Date()})`)
.with_endpoint(Settings.AWS_IOT_ENDPOINT)
.with_credentials(aws_region, aws_accesskeyid, aws_secretaccesskey, aws_session_token)
.with_keep_alive_seconds(30)
.build();
Next, we needed to create an MQTT client.
Here's an example of the code snippet:
const client = new mqtt.MqttClient();
Finally, we established a new connection using the MQTT client and the previously created configuration.
Here's an example of the code snippet:
connection = client.new_connection(config);
connection.connect();
This connection has event listeners attached to it, such as connect, interrupt, resume, disconnect, and error.
To subscribe or publish to a topic, we used the following code snippet:
let topicSubscription = await connection.subscribe("test/topic", mqtt.QoS.AtLeastOnce, handleMessageReceived);
function handleMessageReceived(topic, payload, dup, qos, retain) {
const decoder = new TextDecoder("utf8");
let message = decoder.decode(new Uint8Array(payload));
message = JSON.parse(message.toString());
console.log(`Message received: topic="${topic}" message="${message}"`);
}
function publish(topicSubscription) {
return connection.publish(subscription.topic, "Hello World!", subscription.qos);
}
async function unsubscribe(topicName) {
await connection.unsubscribe(topicName);
}
In the updated code, we no longer use the on('message')
listener. Instead, we provide a callback function while subscribing to a topic.
To end the MQTT connection, we can use the connection.disconnect()
method.
For more information and examples, you can refer to the following resources:
GitHub sample for custom authorizer connection: https://github.com/aws/aws-iot-device-sdk-js-v2/blob/main/samples/browser/custom_authorizer_connect/index.js
AWS provided sample for MQTT5 Protocol: https://github.com/aws/aws-iot-device-sdk-js-v2/blob/main/samples/browser/pub_sub_mqtt5/index.ts
I hope this simplified explanation helps you better understand the steps involved in working with AWS IoT and resolving issues related to the aws-iot-device-sdk.