in src/MQTTDisplay.js [165:260]
function MQTTSubscription(props) {
const [isConnected, setIsConnected] = useState(false);
const [mqttClient, setMqttClient] = useState();
const [messages, setMessages] = useState([]);
useEffect(() => {
connectToAwsIot();
return () => {
// this gets called when component is destroyed...
//https://github.com/mqttjs/MQTT.js/blob/master/README.md#end
console.log(`Ended subscription to '${props.topic}'...`);
};
},[]); // the "[]" causes this to execute just once
async function connectToAwsIot() {
// mqtt clients require a unique clientId; we generate one below
var clientId = 'mqtt-explorer-' + (Math.floor((Math.random() * 100000) + 1));
// get credentials and, from them, extract key, secret key, and session token
// Amplify's auth functionality makes this easy for us...
var currentCredentials = await Auth.currentCredentials();
var essentialCredentials = Auth.essentialCredentials(currentCredentials);
// Create an MQTT client
var newMqttClient = AWSIoTData.device({
region: AWSConfiguration.region,
host:AWSConfiguration.host,
clientId: clientId,
protocol: 'wss',
maximumReconnectTimeMs: 8000,
debug: true,
accessKeyId: essentialCredentials.accessKeyId,
secretKey: essentialCredentials.secretAccessKey,
sessionToken: essentialCredentials.sessionToken
});
// On connect, update status
newMqttClient.on('connect', function() {
setIsConnected(true);
newMqttClient.subscribe(props.topic);
console.log('Connected to AWS IoT!');
console.log(`Subscribed to ${props.topic}`);
});
// add event handler for received messages
newMqttClient.on('message', function(topic, payload) {
var myDate = new Date().toLocaleDateString() + " " + new Date().toLocaleTimeString();
var newMessage = `${myDate} - topic '${topic}' - \n ${payload.toString()}`;
setMessages(prevMessages => [...prevMessages, newMessage]);
console.log(newMessage);
});
// update state to track mqtt client
setMqttClient(newMqttClient);
}
function handleUnsubscribe(e) {
// stop submit button from refreshing entire page
e.preventDefault();
// end subscription; I think this could be added to the return() of the useEffect(), as an "onUnmount" handler,
// but I received an erropr when I tried it. I might be doing something wrong but for now, it works with the commands
// below...
mqttClient.end(false);
setIsConnected(false);
// remove subscription from parent component, thus killing this component...
props.removeSubscription(props.topic);
}
return (
<div className="MQTTSubscription">
Topic Filter: "{props.topic}" ({isConnected ? "connected" : "not connected"})
<form onSubmit={handleUnsubscribe}>
<button type="submit">Unsubscribe</button>
</form>
<br/><br/>
{messages.map((message,index) => {
return (
<li key={index} className="markdown">
{message}
</li>
);
})}
</div>
);
}