From cefed102af1b60c8d5d453f8af3531d1b973a18f Mon Sep 17 00:00:00 2001 From: Damien Albisson Date: Thu, 4 Jul 2024 14:26:53 +0200 Subject: [PATCH] Can't try to connect to two brokers at the same time and if on different page stop trying to connect --- .../after_setup_pages/connections_page.dart | 98 +++++++++++++++++++ lib/utils/utils_functions.dart | 93 +++++++++--------- lib/widgets/utils_widgets/utils_widgets.dart | 82 ---------------- 3 files changed, 143 insertions(+), 130 deletions(-) diff --git a/lib/pages/after_setup_pages/connections_page.dart b/lib/pages/after_setup_pages/connections_page.dart index bf9632c..44dd614 100644 --- a/lib/pages/after_setup_pages/connections_page.dart +++ b/lib/pages/after_setup_pages/connections_page.dart @@ -1,5 +1,9 @@ import 'package:flutter/material.dart'; import 'package:panduza_sandbox_flutter/pages/after_setup_pages/add_cloud_or_self_managed.dart'; +import 'package:panduza_sandbox_flutter/pages/after_setup_pages/userspace_page.dart'; +import 'package:panduza_sandbox_flutter/pages/setup_pages/authentification_page.dart'; +import 'package:panduza_sandbox_flutter/utils/utils_functions.dart'; +import 'package:panduza_sandbox_flutter/utils/utils_objects/broker_connection_info.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:panduza_sandbox_flutter/utils/const.dart'; @@ -28,6 +32,99 @@ class _ConnectionsPageState extends State { late final SharedPreferences _prefs; late final _prefsFuture = SharedPreferences.getInstance().then((v) => _prefs = v); + // If user is trying to connect to a broker + bool isConnecting = false; + + // Connection list display on the home page load from the disk + Widget getConnectionsButtonsList(SharedPreferences prefs, List platformNames, + BuildContext context, State state) { + return ListView.separated( + padding: const EdgeInsets.all(20), + itemCount: platformNames.length, + itemBuilder: (BuildContext context, int index) { + return MouseRegion( + cursor: SystemMouseCursors.click, + child: GestureDetector( + child: Container( + padding: const EdgeInsets.all(10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: black, + ), + child: Row ( + children: [ + getCloudOrLocalIcon((prefs.getStringList(platformNames[index]) as List)[3]), + getConnectionButton(prefs, platformNames, index), + Column( + children: [ + getEditConnectionButton(prefs, platformNames, index, context, state), + getDeleteConnectionButton(prefs, platformNames, index, context, state) + ], + ), + ] + ) + ), + // If the user click on a connection, it will try to connect + // to the mqtt broker if it fail then a small banner will appear + // else he will be redirect on the userpage corresponding + onTap: () { + String host = (prefs.getStringList(platformNames[index]) as List)[1]; + String port = (prefs.getStringList(platformNames[index]) as List)[2]; + + // Here check if it's local or cloud connection + String isCloud = (prefs.getStringList(platformNames[index]) as List)[3]; + + if (isCloud == "1") { + // authentification page in the cloud + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => AuthentificationPage( + hostIp: host, + port: port + ) + ), + ); + } else { + // Try connecting only if connection has not been tried on another broker + if (!isConnecting) { + isConnecting = true; + // If local just permit to user to go on the broker directly + tryConnecting(host, port, "", "").then((client) { + if (isConnecting) { + if (client != null) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => UserspacePage( + brokerConnectionInfo: BrokerConnectionInfo( + host, + int.parse(port), + client + ), + ) + ), + ).then((value) { + isConnecting = false; + client.disconnect(); + }); + } else { + isConnecting = false; + showMyDialogError(context, "Connection to the broker failed"); + } + } + }); + } + } + }, + ), + ); + }, + separatorBuilder: (context, index) => const Divider(), + ); + } + + @override Widget build(BuildContext context) { @@ -56,6 +153,7 @@ class _ConnectionsPageState extends State { // Button to add a connection floatingActionButton: FloatingActionButton( onPressed: () async { + isConnecting = false; await Navigator.push( context, MaterialPageRoute( diff --git a/lib/utils/utils_functions.dart b/lib/utils/utils_functions.dart index 3b9c3a7..fabf54a 100644 --- a/lib/utils/utils_functions.dart +++ b/lib/utils/utils_functions.dart @@ -13,7 +13,7 @@ import 'package:fluttertoast/fluttertoast.dart'; import 'package:panduza_sandbox_flutter/utils/const.dart'; late MqttServerClient _client; -bool _isConnecting = false; + final _chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890'; final Random _rnd = Random(); @@ -174,58 +174,55 @@ String generateRandomMqttIdentifier() { Future tryConnecting(String host, String portStr, String username, String password) async { - if (!_isConnecting) { - _isConnecting = true; - try { - - int port = int.parse(portStr); - - - _client = MqttServerClient.withPort( - host, generateRandomMqttIdentifier(), port); - _client.setProtocolV311(); - - _client.keepAlivePeriod = 20; - - await _client.connect(username, password); - - _client.onConnected = () { - print("MQTT connected"); - }; - - _isConnecting = false; - return _client; - } catch (error) { - print(error); - - _isConnecting = false; - if (Platform.isAndroid || Platform.isIOS) { - Fluttertoast.showToast( - msg: "Connection failed", - textColor: Colors.black, - gravity: ToastGravity.BOTTOM, - backgroundColor: Colors.red, - toastLength: Toast.LENGTH_LONG - ); - } - - // never return because _client not init - return null; + try { + + int port = int.parse(portStr); + + _client = MqttServerClient.withPort( + host, generateRandomMqttIdentifier(), port); + _client.setProtocolV311(); + + _client.keepAlivePeriod = 5; + + // Let 5 sec to connect + _client.connectTimeoutPeriod = 5000; + + await _client.connect(username, password); + + _client.onConnected = () { + print("MQTT connected"); + }; + + return _client; + } catch (error) { + print(error); + + if (Platform.isAndroid || Platform.isIOS) { + Fluttertoast.showToast( + msg: "Connection failed", + textColor: Colors.black, + gravity: ToastGravity.BOTTOM, + backgroundColor: Colors.red, + toastLength: Toast.LENGTH_LONG + ); } + + // never return because _client not init + return null; } - if (Platform.isAndroid || Platform.isIOS) { - Fluttertoast.showToast( - msg: "A connection is already in process", - textColor: Colors.black, - gravity: ToastGravity.BOTTOM, - backgroundColor: Colors.red, - toastLength: Toast.LENGTH_LONG - ); - } + // if (Platform.isAndroid || Platform.isIOS) { + // Fluttertoast.showToast( + // msg: "A connection is already in process", + // textColor: Colors.black, + // gravity: ToastGravity.BOTTOM, + // backgroundColor: Colors.red, + // toastLength: Toast.LENGTH_LONG + // ); + // } - return null; + // return null; } // If user mistake show a pop up to describe his mistake with diff --git a/lib/widgets/utils_widgets/utils_widgets.dart b/lib/widgets/utils_widgets/utils_widgets.dart index 5cb1fd8..67fb923 100644 --- a/lib/widgets/utils_widgets/utils_widgets.dart +++ b/lib/widgets/utils_widgets/utils_widgets.dart @@ -377,85 +377,3 @@ Widget getSimpleTextField(BuildContext context, TextEditingController ctrl, style: Theme.of(context).textTheme.displayMedium ); } - -// Connection list display on the home page load from the disk -Widget getConnectionsButtonsList(SharedPreferences prefs, List platformNames, - BuildContext context, State state) { - return ListView.separated( - padding: const EdgeInsets.all(20), - itemCount: platformNames.length, - itemBuilder: (BuildContext context, int index) { - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - child: Container( - padding: const EdgeInsets.all(10), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: black, - ), - child: Row ( - children: [ - getCloudOrLocalIcon((prefs.getStringList(platformNames[index]) as List)[3]), - getConnectionButton(prefs, platformNames, index), - Column( - children: [ - getEditConnectionButton(prefs, platformNames, index, context, state), - getDeleteConnectionButton(prefs, platformNames, index, context, state) - ], - ), - ] - ) - ), - // If the user click on a connection, it will try to connect - // to the mqtt broker if it fail then a small banner will appear - // else he will be redirect on the userpage corresponding - onTap: () { - String host = (prefs.getStringList(platformNames[index]) as List)[1]; - String port = (prefs.getStringList(platformNames[index]) as List)[2]; - - // Here check if it's local or cloud connection - String isCloud = (prefs.getStringList(platformNames[index]) as List)[3]; - - if (isCloud == "1") { - // authentification page in the cloud - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => AuthentificationPage( - hostIp: host, - port: port - ) - ), - ); - } else { - // If local just permit to user to go on the broker directly - tryConnecting(host, port, "", "").then((client) { - if (client != null) { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => UserspacePage( - brokerConnectionInfo: BrokerConnectionInfo( - host, - int.parse(port), - client - ), - ) - ), - ).then((value) { - client.disconnect(); - }); - } else { - showMyDialogError(context, "Connection to the broker failed"); - } - }); - } - }, - ), - ); - }, - separatorBuilder: (context, index) => const Divider(), - ); -} -