I have an EMQX cloud
environment where the MQTTX
client is connecting to, this works and i can publish and receive messages.
MQTTX Configuration
But when trying to connect to the same service in React-Native
, it does not work and i keep receiving Socket Closed
, undefined
or Timeout
errors.
My Code
import init from "react_native_mqtt";
import AsyncStorage from "@react-native-async-storage/async-storage";
init({
size: 10000,
storageBackend: AsyncStorage,
defaultExpires: 1000 * 3600 * 24,
enableCache: true,
reconnect: true,
sync: {},
});
const options = {
host: "a1b2c3d4.oxo.oco-southeast1.emqxsl.com",
port: 8883,
path: "/mqtt",
id: "id_" + parseInt(id.toString()),
};
const client = new Paho.MQTT.Client(options.host, options.port, options.path, options.id);
export const App: FC<HomeStackScreenProps<"Home">> = ({ navigation, route }) => {
const connect = async () => {
if (client.isConnected()) {
if (__DEV__) console.log("🚫 - Previous client connected? ", client.isConnected());
if (__DEV__) console.log("🚫 - Closing previous client? ", client.disconnect());
onConnect();
} else {
client.connect({
timeout: 3,
userName: "test",
password: "**********",
keepAliveInterval: 60,
cleanSession: true,
useSSL: true,
onSuccess: onConnect,
onFailure: onFailure,
reconnect: true,
mqttVersion: 4,
});
console.log(client);
setStatus("isFetching");
}
};
}
The solution for this problem is basically using a whole other library which supports mqtts
protocols. I used react_native_mqtt
which was fine at first but did not work with an online service like emqx cloud
. so I changed my whole process to the library sp-react-native-mqtt
. With some small, only every file that uses MQTT
, code changes it worked perfectly!
My code
import MQTT from "sp-react-native-mqtt";
const new_client = MQTT.createClient({
clientId: options.clientId,
uri: "mqtts://a1b2c3d4.oxo.oco-southeast1.emqxsl.com:8883",
host: "a1b2c3d4.oxo.oco-southeast1.emqxsl.com",
port: 8883,
protocol: "mqtts",
tls: true,
keepalive: 60,
clean: true,
auth: true,
user: "xoxo",
pass: "xoxo1234",
});
export const App: FC<HomeStackScreenProps<"Home">> = ({ navigation, route }) => {
useEffect(() => {
new_client
.then((client) => {
client.on("closed", () => {
console.log("mqtt.event.closed");
});
client.on("error", (msg) => {
console.log("mqtt.event.error", msg);
onFailure(msg);
});
client.on("message", (msg) => {
console.log(msg)
});
client.on("connect", () => {
onConnect();
// You can access new_client.publish here
client.publish("test", "test", 0, false);
});
return client; // return the client for further chaining
})
.catch((err) => {
console.log(err);
});
}, []);
return (
// Some components
)
}
Eventually after many debugging on Android
it worked on both platforms and was connected to the EMQX Cloud
. The comment of hardillb
was part of the solution. With this library, the protocol is mqtts
which is needed to connect to EMQX Cloud
. One can also use websockets but I had to use mqtts.