Skip to content

Instantly share code, notes, and snippets.

@roniseti
Created March 24, 2024 22:59
Show Gist options
  • Select an option

  • Save roniseti/868cb3782521ae4fd4f0e99ccda9ab3d to your computer and use it in GitHub Desktop.

Select an option

Save roniseti/868cb3782521ae4fd4f0e99ccda9ab3d to your computer and use it in GitHub Desktop.
Flutter MQTT Client Wrapper
import 'dart:developer';
import 'dart:math' as math;
import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';
enum MqttCurrentConnectionState {
idle,
connecting,
connected,
disconnected,
errorWhenConnecting
}
enum MqttSubscriptionState {
idle,
subscribed
}
class MQTTClientWrapper {
MQTTClientWrapper(
this.onConnectedCallback,
this.onReceivedCallback, {
required this.topics,
this.username = '',
this.password = '',
required this.serverAddress
}) : super();
final Function() onConnectedCallback; // VoidCallback
final Function(String) onReceivedCallback;
final List<String> topics;
final String username;
final String password;
final String serverAddress;
late MqttServerClient client;
MqttCurrentConnectionState connectionState = MqttCurrentConnectionState.idle;
MqttSubscriptionState subscriptionState = MqttSubscriptionState.idle;
void prepareMqttClient() async {
_setupMqttClient();
await _connectClient();
_subscribeToTopic(topics);
}
Future<void> _connectClient() async {
try {
log('MQTTClientWrapper:: client connecting....');
connectionState = MqttCurrentConnectionState.connecting;
await client.connect(username, password);
} on Exception catch (e) {
log('MQTTClientWrapper::client exception - $e');
connectionState = MqttCurrentConnectionState.errorWhenConnecting;
client.disconnect();
}
if (client.connectionStatus!.state == MqttConnectionState.connected) {
connectionState = MqttCurrentConnectionState.connected;
log('MQTTClientWrapper:: client connected');
} else {
log(
'MQTTClientWrapper::ERROR client connection failed - disconnecting, status is ${client.connectionStatus}');
connectionState = MqttCurrentConnectionState.errorWhenConnecting;
client.disconnect();
}
}
void _setupMqttClient() {
client = MqttServerClient.withPort(serverAddress, '${DateTime.now().millisecondsSinceEpoch ~/ 1000}-${generateRandomString(len: 12)}', 1883);
client.autoReconnect = true;
client.logging(on: false);
client.keepAlivePeriod = 60;
client.onDisconnected = _onDisconnected;
client.onConnected = _onConnected;
client.onSubscribed = _onSubscribed;
}
void _subscribeToTopic(List<String> topics) {
for (var topic in topics) {
log('MQTTClientWrapper::Subscribing to the $topic topic');
client.subscribe(topic, MqttQos.exactlyOnce);
}
client.updates!.listen((List<MqttReceivedMessage<MqttMessage>> c) {
final recMess = c[0].payload as MqttPublishMessage;
final pt = MqttPublishPayload.bytesToStringAsString(recMess.payload.message);
print('MQTTClientWrapper::GOT A NEW MESSAGE $pt');
onReceivedCallback(pt);
});
}
void publishMessage(String message, String topicName) {
final MqttClientPayloadBuilder builder = MqttClientPayloadBuilder();
builder.addString(message);
print('MQTTClientWrapper::Publishing message $message to topic ${topicName}');
client.publishMessage(topicName, MqttQos.exactlyOnce, builder.payload!);
}
void _onSubscribed(String topic) {
log('MQTTClientWrapper::Subscription confirmed for topic $topic');
subscriptionState = MqttSubscriptionState.subscribed;
}
void _onDisconnected() {
log('MQTTClientWrapper::OnDisconnected client callback - Client disconnection');
// if (client.connectionStatus!.returnCode == MqttConnectReturnCode.solicited) {
// print('MQTTClientWrapper::OnDisconnected callback is solicited, this is correct');
// }
connectionState = MqttCurrentConnectionState.disconnected;
onConnectedCallback();
}
void _onConnected() {
connectionState = MqttCurrentConnectionState.connected;
log('MQTTClientWrapper::OnConnected client callback - Client connection was successful');
onConnectedCallback();
}
void disconnect() {
client.disconnect();
log('MQTT Disconnected');
}
}
String generateRandomString({required int len, String chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890'}) {
var r = math.Random();
return List.generate(len, (index) => chars[r.nextInt(chars.length)]).join();
}
@roniseti
Copy link
Author

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